/*****************************************************************************
 * x264.h: x264 public header
 *****************************************************************************
 * Copyright (C) 2003-2018 x264 project
 *
 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
 *          Loren Merritt <lorenm@u.washington.edu>
 *          Fiona Glaser <fiona@x264.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
 *
 * This program is also available under a commercial proprietary license.
 * For more information, contact us at licensing@x264.com.
 *****************************************************************************/

#ifndef X264_X264_H
#define X264_X264_H

#ifdef __cplusplus
extern "C" {
#endif

#if !defined(_STDINT_H) && !defined(_STDINT_H_) && !defined(_STDINT_H_INCLUDED) && !defined(_STDINT) &&\
    !defined(_SYS_STDINT_H_) && !defined(_INTTYPES_H) && !defined(_INTTYPES_H_) && !defined(_INTTYPES)
# ifdef _MSC_VER
#  pragma message("You must include stdint.h or inttypes.h before x264.h")
# else
#  warning You must include stdint.h or inttypes.h before x264.h
# endif
#endif

#include <stdarg.h>

#include "x264_config.h"

#define X264_BUILD 157

/* Application developers planning to link against a shared library version of
 * libx264 from a Microsoft Visual Studio or similar development environment
 * will need to define X264_API_IMPORTS before including this header.
 * This clause does not apply to MinGW, similar development environments, or non
 * Windows platforms. */
#ifdef X264_API_IMPORTS
#define X264_API __declspec(dllimport)
#else
#define X264_API
#endif

/* x264_t:
 *      opaque handler for encoder */
typedef struct x264_t x264_t;

/****************************************************************************
 * NAL structure and functions
 ****************************************************************************/

enum nal_unit_type_e
{
    NAL_UNKNOWN     = 0,
    NAL_SLICE       = 1,
    NAL_SLICE_DPA   = 2,
    NAL_SLICE_DPB   = 3,
    NAL_SLICE_DPC   = 4,
    NAL_SLICE_IDR   = 5,    /* ref_idc != 0 */
    NAL_SEI         = 6,    /* ref_idc == 0 */
    NAL_SPS         = 7,
    NAL_PPS         = 8,
    NAL_AUD         = 9,
    NAL_FILLER      = 12,
    /* ref_idc == 0 for 6,9,10,11,12 */
};
enum nal_priority_e
{
    NAL_PRIORITY_DISPOSABLE = 0,
    NAL_PRIORITY_LOW        = 1,
    NAL_PRIORITY_HIGH       = 2,
    NAL_PRIORITY_HIGHEST    = 3,
};

/* The data within the payload is already NAL-encapsulated; the ref_idc and type
 * are merely in the struct for easy access by the calling application.
 * All data returned in an x264_nal_t, including the data in p_payload, is no longer
 * valid after the next call to x264_encoder_encode.  Thus it must be used or copied
 * before calling x264_encoder_encode or x264_encoder_headers again. */
typedef struct x264_nal_t
{
    int i_ref_idc;  /* nal_priority_e */
    int i_type;     /* nal_unit_type_e */
    int b_long_startcode;
    int i_first_mb; /* If this NAL is a slice, the index of the first MB in the slice. */
    int i_last_mb;  /* If this NAL is a slice, the index of the last MB in the slice. */

    /* Size of payload (including any padding) in bytes. */
    int     i_payload;
    /* If param->b_annexb is set, Annex-B bytestream with startcode.
     * Otherwise, startcode is replaced with a 4-byte size.
     * This size is the size used in mp4/similar muxing; it is equal to i_payload-4 */
    uint8_t *p_payload;

    /* Size of padding in bytes. */
    int i_padding;
} x264_nal_t;

/****************************************************************************
 * Encoder parameters
 ****************************************************************************/
/* CPU flags */

/* x86 */
#define X264_CPU_MMX                (1<<0)
#define X264_CPU_MMX2               (1<<1)  /* MMX2 aka MMXEXT aka ISSE */
#define X264_CPU_MMXEXT             X264_CPU_MMX2
#define X264_CPU_SSE                (1<<2)
#define X264_CPU_SSE2               (1<<3)
#define X264_CPU_LZCNT              (1<<4)
#define X264_CPU_SSE3               (1<<5)
#define X264_CPU_SSSE3              (1<<6)
#define X264_CPU_SSE4               (1<<7)  /* SSE4.1 */
#define X264_CPU_SSE42              (1<<8)  /* SSE4.2 */
#define X264_CPU_AVX                (1<<9)  /* Requires OS support even if YMM registers aren't used */
#define X264_CPU_XOP                (1<<10) /* AMD XOP */
#define X264_CPU_FMA4               (1<<11) /* AMD FMA4 */
#define X264_CPU_FMA3               (1<<12)
#define X264_CPU_BMI1               (1<<13)
#define X264_CPU_BMI2               (1<<14)
#define X264_CPU_AVX2               (1<<15)
#define X264_CPU_AVX512             (1<<16) /* AVX-512 {F, CD, BW, DQ, VL}, requires OS support */
/* x86 modifiers */
#define X264_CPU_CACHELINE_32       (1<<17) /* avoid memory loads that span the border between two cachelines */
#define X264_CPU_CACHELINE_64       (1<<18) /* 32/64 is the size of a cacheline in bytes */
#define X264_CPU_SSE2_IS_SLOW       (1<<19) /* avoid most SSE2 functions on Athlon64 */
#define X264_CPU_SSE2_IS_FAST       (1<<20) /* a few functions are only faster on Core2 and Phenom */
#define X264_CPU_SLOW_SHUFFLE       (1<<21) /* The Conroe has a slow shuffle unit (relative to overall SSE performance) */
#define X264_CPU_STACK_MOD4         (1<<22) /* if stack is only mod4 and not mod16 */
#define X264_CPU_SLOW_ATOM          (1<<23) /* The Atom is terrible: slow SSE unaligned loads, slow
                                             * SIMD multiplies, slow SIMD variable shifts, slow pshufb,
                                             * cacheline split penalties -- gather everything here that
                                             * isn't shared by other CPUs to avoid making half a dozen
                                             * new SLOW flags. */
#define X264_CPU_SLOW_PSHUFB        (1<<24) /* such as on the Intel Atom */
#define X264_CPU_SLOW_PALIGNR       (1<<25) /* such as on the AMD Bobcat */

/* PowerPC */
#define X264_CPU_ALTIVEC         0x0000001

/* ARM and AArch64 */
#define X264_CPU_ARMV6           0x0000001
#define X264_CPU_NEON            0x0000002  /* ARM NEON */
#define X264_CPU_FAST_NEON_MRC   0x0000004  /* Transfer from NEON to ARM register is fast (Cortex-A9) */
#define X264_CPU_ARMV8           0x0000008

/* MIPS */
#define X264_CPU_MSA             0x0000001  /* MIPS MSA */

/* Analyse flags */
#define X264_ANALYSE_I4x4       0x0001  /* Analyse i4x4 */
#define X264_ANALYSE_I8x8       0x0002  /* Analyse i8x8 (requires 8x8 transform) */
#define X264_ANALYSE_PSUB16x16  0x0010  /* Analyse p16x8, p8x16 and p8x8 */
#define X264_ANALYSE_PSUB8x8    0x0020  /* Analyse p8x4, p4x8, p4x4 */
#define X264_ANALYSE_BSUB16x16  0x0100  /* Analyse b16x8, b8x16 and b8x8 */

#define X264_DIRECT_PRED_NONE        0
#define X264_DIRECT_PRED_SPATIAL     1
#define X264_DIRECT_PRED_TEMPORAL    2
#define X264_DIRECT_PRED_AUTO        3
#define X264_ME_DIA                  0
#define X264_ME_HEX                  1
#define X264_ME_UMH                  2
#define X264_ME_ESA                  3
#define X264_ME_TESA                 4
#define X264_CQM_FLAT                0
#define X264_CQM_JVT                 1
#define X264_CQM_CUSTOM              2
#define X264_RC_CQP                  0
#define X264_RC_CRF                  1
#define X264_RC_ABR                  2
#define X264_QP_AUTO                 0
#define X264_AQ_NONE                 0
#define X264_AQ_VARIANCE             1
#define X264_AQ_AUTOVARIANCE         2
#define X264_AQ_AUTOVARIANCE_BIASED  3
#define X264_B_ADAPT_NONE            0
#define X264_B_ADAPT_FAST            1
#define X264_B_ADAPT_TRELLIS         2
#define X264_WEIGHTP_NONE            0
#define X264_WEIGHTP_SIMPLE          1
#define X264_WEIGHTP_SMART           2
#define X264_B_PYRAMID_NONE          0
#define X264_B_PYRAMID_STRICT        1
#define X264_B_PYRAMID_NORMAL        2
#define X264_KEYINT_MIN_AUTO         0
#define X264_KEYINT_MAX_INFINITE     (1<<30)

/* AVC-Intra flavors */
#define X264_AVCINTRA_FLAVOR_PANASONIC 0
#define X264_AVCINTRA_FLAVOR_SONY      1

static const char * const x264_direct_pred_names[] = { "none", "spatial", "temporal", "auto", 0 };
static const char * const x264_motion_est_names[] = { "dia", "hex", "umh", "esa", "tesa", 0 };
static const char * const x264_b_pyramid_names[] = { "none", "strict", "normal", 0 };
static const char * const x264_overscan_names[] = { "undef", "show", "crop", 0 };
static const char * const x264_vidformat_names[] = { "component", "pal", "ntsc", "secam", "mac", "undef", 0 };
static const char * const x264_fullrange_names[] = { "off", "on", 0 };
static const char * const x264_colorprim_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m", "smpte240m", "film", "bt2020", "smpte428",
                                                     "smpte431", "smpte432", 0 };
static const char * const x264_transfer_names[] = { "", "bt709", "undef", "", "bt470m", "bt470bg", "smpte170m", "smpte240m", "linear", "log100", "log316",
                                                    "iec61966-2-4", "bt1361e", "iec61966-2-1", "bt2020-10", "bt2020-12", "smpte2084", "smpte428", "arib-std-b67", 0 };
static const char * const x264_colmatrix_names[] = { "GBR", "bt709", "undef", "", "fcc", "bt470bg", "smpte170m", "smpte240m", "YCgCo", "bt2020nc", "bt2020c",
                                                     "smpte2085", "chroma-derived-nc", "chroma-derived-c", "ICtCp", 0 };
static const char * const x264_nal_hrd_names[] = { "none", "vbr", "cbr", 0 };
static const char * const x264_avcintra_flavor_names[] = { "panasonic", "sony", 0 };

/* Colorspace type */
#define X264_CSP_MASK           0x00ff  /* */
#define X264_CSP_NONE           0x0000  /* Invalid mode     */
#define X264_CSP_I400           0x0001  /* monochrome 4:0:0 */
#define X264_CSP_I420           0x0002  /* yuv 4:2:0 planar */
#define X264_CSP_YV12           0x0003  /* yvu 4:2:0 planar */
#define X264_CSP_NV12           0x0004  /* yuv 4:2:0, with one y plane and one packed u+v */
#define X264_CSP_NV21           0x0005  /* yuv 4:2:0, with one y plane and one packed v+u */
#define X264_CSP_I422           0x0006  /* yuv 4:2:2 planar */
#define X264_CSP_YV16           0x0007  /* yvu 4:2:2 planar */
#define X264_CSP_NV16           0x0008  /* yuv 4:2:2, with one y plane and one packed u+v */
#define X264_CSP_YUYV           0x0009  /* yuyv 4:2:2 packed */
#define X264_CSP_UYVY           0x000a  /* uyvy 4:2:2 packed */
#define X264_CSP_V210           0x000b  /* 10-bit yuv 4:2:2 packed in 32 */
#define X264_CSP_I444           0x000c  /* yuv 4:4:4 planar */
#define X264_CSP_YV24           0x000d  /* yvu 4:4:4 planar */
#define X264_CSP_BGR            0x000e  /* packed bgr 24bits */
#define X264_CSP_BGRA           0x000f  /* packed bgr 32bits */
#define X264_CSP_RGB            0x0010  /* packed rgb 24bits */
#define X264_CSP_MAX            0x0011  /* end of list */
#define X264_CSP_VFLIP          0x1000  /* the csp is vertically flipped */
#define X264_CSP_HIGH_DEPTH     0x2000  /* the csp has a depth of 16 bits per pixel component */

/* Slice type */
#define X264_TYPE_AUTO          0x0000  /* Let x264 choose the right type */
#define X264_TYPE_IDR           0x0001
#define X264_TYPE_I             0x0002
#define X264_TYPE_P             0x0003
#define X264_TYPE_BREF          0x0004  /* Non-disposable B-frame */
#define X264_TYPE_B             0x0005
#define X264_TYPE_KEYFRAME      0x0006  /* IDR or I depending on b_open_gop option */
#define IS_X264_TYPE_I(x) ((x)==X264_TYPE_I || (x)==X264_TYPE_IDR || (x)==X264_TYPE_KEYFRAME)
#define IS_X264_TYPE_B(x) ((x)==X264_TYPE_B || (x)==X264_TYPE_BREF)

/* Log level */
#define X264_LOG_NONE          (-1)
#define X264_LOG_ERROR          0
#define X264_LOG_WARNING        1
#define X264_LOG_INFO           2
#define X264_LOG_DEBUG          3

/* Threading */
#define X264_THREADS_AUTO 0 /* Automatically select optimal number of threads */
#define X264_SYNC_LOOKAHEAD_AUTO (-1) /* Automatically select optimal lookahead thread buffer size */

/* HRD */
#define X264_NAL_HRD_NONE            0
#define X264_NAL_HRD_VBR             1
#define X264_NAL_HRD_CBR             2

/* Zones: override ratecontrol or other options for specific sections of the video.
 * See x264_encoder_reconfig() for which options can be changed.
 * If zones overlap, whichever comes later in the list takes precedence. */
typedef struct x264_zone_t
{
    // 帧的开始和结束帧号
    int i_start, i_end; /* range of frame numbers */
    // 是否强制qp
    int b_force_qp; /* whether to use qp vs bitrate factor */
    // qp值
    int i_qp;
    // 码率因子
    float f_bitrate_factor;
    // 参数
    struct x264_param_t *param;
} x264_zone_t;

typedef struct x264_param_t
{
    /* CPU flags */
    unsigned int cpu;
    int         i_threads;           /* 编码的线程数 encode multiple frames in parallel */
    // "i_lookahead_threads"是x264_param_t结构体中的一个成员变量，用于设置编码器中前向预测所使用的线程数。前向预测是一种视频编码技术，它可以通过分析前面的帧来找到当前帧中的运动信息。在x264中，前向预测是通过在后续帧中查找和当前帧最相似的部分来实现的。这一过程需要对后续帧进行检索和匹配，因此会消耗一定的计算资源。为了提高性能，x264提供了多线程的支持，在多个线程中同时进行前向预测。"i_lookahead_threads"这个参数就是用来指定这些线程的数量。需要注意的是，增加预测线程数理论上可以提高编码器的性能，但也会对CPU带来更大的计算压力，因此在设置时应该根据实际情况进行权衡。
    int         i_lookahead_threads; /* 前向预测的线程数 multiple threads for lookahead analysis */
    // "b_sliced_threads"是x264_param_t结构体中的一个布尔型成员变量，用于控制编码器中是否使用分片线程。分片线程是一种多线程编码技术，它可以将一帧图像分成多片进行编码，每片分别由一个线程进行处理，最后将结果合并。这种技术可以充分利用多核CPU的优势，提高编码效率。在x264中，默认情况下会启用分片线程。但在某些情况下，如编码低分辨率、低码率的视频时，启用分片线程可能会导致编码效率降低。此时，可以通过将"b_sliced_threads"设置为false来禁用分片线程。
    int         b_sliced_threads;  /* 多slice编码 Whether to use slice-based threading. */
    // "b_deterministic"是x264_param_t结构体中的一个布尔型成员变量，用于控制编码器中是否启用确定性编码。在x264中，有一些特性是不确定性的，即在相同的输入下，它们可能会产生不同的输出。而确定性编码则是指在相同的输入下，每次编码的输出都应该是相同的。在某些应用场景下，如测试、比较、索引等，需要确保编码结果的确定性。为了实现这个目的，可以将"b_deterministic"设置为true，从而启用确定性编码。但需要注意的是，启用确定性编码可能会降低编码质量和/或编码效率。
    int         b_deterministic; /* whether to allow non-deterministic optimizations when threaded */
    // "b_cpu_independent"是x264_param_t结构体中的一个布尔型成员变量，用于控制编码器的一些参数是否与CPU相关。默认情况下，x264会根据当前使用的CPU来自动选择一些参数设置，以提高编码效率。但在一些场景下，可能需要将这些参数设置为与CPU无关的固定值，以保证编码结果的一致性。此时，可以将"b_cpu_independent"设置为true，从而禁用针对特定CPU的参数设置。需要注意的是，禁用CPU相关设置可能会导致编码效率降低，甚至影响编码质量。因此，应该根据实际情况权衡是否要启用这个选项。
    int         b_cpu_independent; /* force canonical behavior rather than cpu-dependent optimal algorithms */
    // "i_sync_lookahead"是x264_param_t结构体中的一个整型成员变量，用于设置编码器中同步前向预测所使用的帧数。在x264中，同步前向预测是一种特殊的前向预测技术，它可以根据未来的几帧预测图像的运动矢量和残差，从而提高编码质量和压缩比。其实现原理是将后续的多帧图像先解码出来，然后与当前帧进行对齐和匹配，最后得到相应的运动矢量和残差。"i_sync_lookahead"用于设置同步前向预测所使用的帧数，即解码出来的后续帧数。可以根据实际情况进行设置，以平衡编码质量和编码速度。需要注意的是，增加同步前向预测使用的帧数可以提高编码的质量，但也会增加编码的延迟和计算量，因此应该根据实际情况进行权衡。
    int         i_sync_lookahead; /* threaded lookahead buffer */

    /* Video Properties */
    // 宽
    int         i_width; 
    // 高
    int         i_height;
    // "i_csp"是x264_param_t结构体中的一个整型成员变量，用于设置编码器的输入图像格式。“i_csp"即"Color Space”，意为颜色空间。在视频编码中，不同的颜色空间有着不同的编码方式，因此需要在编码前将原始图像转换到所需的颜色空间。x264支持多种颜色空间的输入格式，包括YUV、RGB、BGR等。具体的输入格式可以通过设置"i_csp"参数来指定。常见的输入格式包括YUV420、YUV422、YUV444等。需要注意的是，在设置这个参数时，应该使用对应编码器所支持的输入格式。如果输入图像格式与编码器不匹配，可能会导致编码失败或产生无效的编码结果。
    int         i_csp;         /* CSP of encoded bitstream */
    // "i_bitdepth"是x264_param_t结构体中的一个整型成员变量，用于设置编码器的位深度。位深度是指每个像素采样的实际比特数，它决定了图像的色深和动态范围。在视频编码中，通常使用8位或10位的位深度来表示。x264支持多种位深度的输入，包括8、9、10、12、14和16位的位深度。可以通过设置"i_bitdepth"参数来指定输入的位深度。需要注意的是，位深度越高，图像质量和色彩表现力都有所提高，但同时也会增加编码器的计算量和码流大小。因此，在设置这个参数时，应该根据实际情况进行权衡。同时，在设置位深度时，也需要注意与颜色空间的匹配，以确保编码结果正确。
    int         i_bitdepth;
    // "i_level_idc"是x264_param_t结构体中的一个整型成员变量，用于设置编码器的H.264 / AVC（Advanced Video Codec）的级别（level）和约束集（constraint set）。在H.264 / AVC编码中，级别是指编码器所支持的最大帧率、最大分辨率、最大码率等参数的限制。而约束集则是指编码器必须遵守的规则。在x264中，"i_level_idc"参数可以用于设置H.264的级别和约束集，以确保编码器所产生的视频可以兼容各种标准设备和播放器。常见的级别有Baseline、Main和High等；而约束集则包括Constrained Baseline、Constrained High、High、High 10和High 422等。需要注意的是，不同的级别和约束集会对编码效率和视频质量产生不同的影响，因此应该根据实际情况进行选择
    int         i_level_idc;
    // 要编码的总帧数
    int         i_frame_total; /* number of frames to encode if known, else 0 */

    /* NAL HRD
     * Uses Buffering and Picture Timing SEIs to signal HRD
     * The HRD in H.264 was not designed with VFR in mind.
     * It is therefore not recommendeded to use NAL HRD with VFR.
     * Furthermore, reconfiguring the VBV (via x264_encoder_reconfig)
     * will currently generate invalid HRD. */

    /* "i_nal_hrd"是x264_param_t结构体中的一个整型成员变量，用于控制编码器的码流控制。在H.264 / AVC编码中，码流控制是指通过控制码率来控制输出码流的大小和质量。x264通过Nal HRD（Network Abstraction Layer Hypothetical Reference Decoder，网络抽象层虚拟参考解码器）来实现码流控制。Nal HRD是H.264标准中一个重要的参考解码器模型，它可以辅助编码器进行码流控制。通过设置"i_nal_hrd"参数，可以控制Nal HRD的使用方式，从而使编码器产生更加稳定和合理的码率。具体地，"i_nal_hrd"参数有3种取值：

- 0：表示禁止使用Nal HRD；
- 1：表示启用Nal HRD；
- 2：表示自动选择是否启用Nal HRD。

需要注意的是，启用Nal HRD可以提高编码器的稳定性和码流控制精度，但同时也会增加编码器的计算量和延迟，因此应该根据实际情况进行权衡。*/
    int         i_nal_hrd;

    struct
    {
        /* they will be reduced to be 0 < x <= 65535 and prime */
        // "i_sar_height"是x264_param_t结构体中的一个整型成员变量，用于设置视频的样本纵向比例。SAR（Sample Aspect Ratio，样本横向比例）和PAR（Pixel Aspect Ratio，像素横向比例）是描述视频分辨率的两个概念。前者是指每个采样单元的横向和纵向的实际像素点数的比值，而后者是指每个像素的横向和纵向的实际像素点数的比值。在x264中，通常使用SAR来描述视频分辨率。"i_sar_height"参数用于设置视频的样本纵向比例，即视频采样单元的纵向像素点数与横向像素点数的比值。通常情况下，SAR的值应该与输出视频的显示设备相匹配，以保证视频的正常播放和显示。
        int         i_sar_height;
        int         i_sar_width;

        /* "i_overscan"是x264_param_t结构体中的一个整型成员变量，用于设置视频的过扫描（overscan）信息。过扫描是指将画面的所有像素都扩展到超出屏幕边界的范围，以保证画面在不同的设备上都能正确地显示。在x264中，可以使用"i_overscan"参数来指定输入视频是否包含过扫描信息。具体来说，"i_overscan"参数有以下几种取值：

- 0：表示输入视频可能包含过扫描信息，但具体情况不确定。
- 1：表示输入视频不包含过扫描信息。
- 2：表示输入视频包含过扫描信息。

需要注意的是，如果输入视频包含过扫描信息，那么在编码时应该保留这些信息，以便在播放时进行正确的裁剪和显示。否则，可能会导致画面变形或无法正常显示。*/
        int         i_overscan;    /* 0=undef, 1=no overscan, 2=overscan */

        /* see h264 annex E for the values of the following */
        // "i_vidformat"是x264_param_t结构体中的一个整型成员变量，用于设置视频输出格式。具体来说，"i_vidformat"参数用于设置输出视频的封装格式和文件扩展名，包括AVI、FLV、MKV、MP4等常见的视频封装格式。x264支持多种不同的封装格式，可以通过设置"i_vidformat"参数来指定输出的格式。需要注意的是，不同的封装格式有着不同的优缺点和使用限制，应该根据实际情况进行选择。同时，在设置封装格式时，也需要考虑目标播放平台和设备的兼容性，以确保输出视频的正常播放和使用。
        int         i_vidformat;
        // "b_fullrange"是x264_param_t结构体中的一个布尔型成员变量，用于控制x264编码器的输入视频是否使用全幅像素值范围。在视频编码中，通常使用的像素值范围是16-235，而不是0-255。这是因为视频信号通常会被传输到模拟电视机上进行播放，而模拟电视的亮度范围一般是16-235，因此在编码时需要将视频信号进行裁剪和调整。而在一些特殊情况下，需要将视频信号的像素值范围扩大到0-255。这就可以通过将"b_fullrange"参数设置为true来实现。需要注意的是，使用全幅像素值范围可能会影响视频的色彩表现力和图像细节，因此应该根据实际情况进行选择。同时，在使用全幅像素值范围时，也需要确保输出视频与播放设备的兼容性。
        int         b_fullrange;
        // 在x264_param_t结构体中，i_colorprim是x264编码器中的一个参数，它控制了颜色原色的范围。颜色原色定义了可以显示的颜色范围。在视频编码中，需要在压缩和解压缩过程中准确地重新生成原始内容的颜色信息。i_colorprim参数允许用户指定在源视频中使用的颜色原色，以便x264在编码过程中保留颜色。它是x264中可用于优化编码过程的几个选项之一，以实现颜色准确性。
        int         i_colorprim;
        // 在x264中，i_transfer是控制转移特性的参数，用于在视频编码期间指定源材料中使用的场景转移特性。转移特性定义了如何从光电信号映射到彩色信号时，电光转换功能会在可见光谱的哪个部分产生重要的不同。这是为了在视频编码期间尽可能准确地重建源材料的颜色信息，避免对色彩的损失或失真。i_transfer参数可以设置为不同的选项，如BT.709、BT.601、SMPTE-240M等，这些选项可以匹配源材料的转移特性，从而优化编码过程以实现更好的色彩准确性。
        int         i_transfer;
        // 在x264中，i_colmatrix参数是用于指定源材料中的色度矩阵，以确保视频编码器在压缩过程中尽可能准确地重建色度信息。色度矩阵定义了如何将原始色彩信息从RGB色彩空间映射到亮度-色度（YCbCr）色彩空间，这为视频编码提供了一些信息。i_colmatrix可以设置为多种不同的选项，如“Identity”、“BT.709”、“BT.601”、“SMPTE-240M”等，以匹配源材料的色度矩阵以及视频编码的要求。i_colmatrix参数通常与其他编码器参数一起使用，以最大限度地提高编码质量并减少对色彩的损失。
        int         i_colmatrix;
        // 在x264中，i_chroma_loc参数用于指定Croma示例的位置。这个参数用于更好地重建颜色信息，在色度重采样时被用来指定色度信息的采样位置。Croma示例的位置可以是“undef”、“left”、“center”、“topleft”、“top”和“bottomleft”等选项，这些选项指定了Chroma的采样和重建规则，以便在编码过程中实现最大的色彩准确性。i_chroma_loc还提供了一些其他的选择，可以适用于许多不同的视频源材料，这些选项可以根据不同的应用场景进行设置。
        int         i_chroma_loc;    /* both top & bottom */
    } vui;

    /* Bitstream parameters */
    // 在x264中，x264_param_t是一个用来设置x264编码器参数的结构体。其中的i_frame_reference参数指定了x264编码器用于在编码视频序列时为每个参考帧保留多少个缓存副本。参考帧通常是x264编码器用来预测下一帧的一个非常重要的信息。因此，在编码期间保留参考帧的缓存副本可以减少编码器的工作量，从而提高编码速度和质量。
    int         i_frame_reference;  /* Maximum number of reference frames */
    /*在x264中，i_dpb_size参数指定了解码图像缓冲区（DPB）的大小。x264编码器在编码H.264视频时会生成许多帧，其中有些是引用了前面的帧。这样的帧需要在解码时引用其它帧的图像。解码时用到的缓存区被称为DPB。i_dpb_size参数定义了DPB缓存区中允许同时拥有的参考帧的最大数量，这对于视频编码器和解码器之间的互操作性非常重要。

DPB的大小取决于编码器参数i_keyint_min和i_keyint_max。i_keyint_min和i_keyint_max分别指定关键帧（I帧）的最小和最大间隔数。i_dpb_size必须大于i_keyint_min和i_keyint_max值的最大值。通常，i_dpb_size的值设置为4到16之间的整数值。设定正确的i_dpb_size值，可以充分利用存储容量，最大程度地提高解码的速度和效率，并提高视频质量。*/
    int         i_dpb_size;         /* Force a DPB size larger than that implied by B-frames and reference frames.
                                     * Useful in combination with interactive error resilience. */
    int         i_keyint_max;       /* Force an IDR keyframe at this interval */
    int         i_keyint_min;       /* Scenecuts closer together than this are coded as I, not IDR. */
    /*在x264编码器中，i_scenecut_threshold参数指定了场景切换检测的敏感度阈值。场景切换是视频序列中的场景变化，例如从一个摄像头到另一个摄像头、镜头旋转等。视频序列中的场景切换会影响码率控制和压缩效率。i_scenecut_threshold参数用于控制编码器在检测到场景切换时的反应程度，这样可以在场景切换时保持视频质量和压缩效率。

i_scenecut_threshold参数的值在0到100之间，值越小表示检测到场景切换的敏感度越高。当场景切换检测到了场景变化，编码器可以选择在场景切换处插入新的关键帧以更好地表示新的场景，以达到最佳的视觉效果和压缩效率。实际上，i_scenecut_threshold与i_keyint_max和i_keyint_min等参数配合使用可以在场景切换时获得最佳的视频质量和压缩效率。*/
    int         i_scenecut_threshold; /* how aggressively to insert extra I frames */
    /*在x264中，b_intra_refresh参数用于启用B帧内部刷新（BIR）的功能，以提高视频的图像质量。BIR技术是一种通过在B帧中插入额外的I帧或P帧来刷新视频序列的方法。这些I帧或P帧在解码时仅用于B帧，这样可以确保B帧的图像质量不会因为向后预测的错误而受到损害。

b_intra_refresh参数通常用于视频流媒体或实时视频传输中。它可以有效地减少编码、传输和解码延迟，同时提高视频的图像质量。b_intra_refresh参数可以设置为2、4、8等数字来指定在多少个B帧之后执行BIR操作。值越小，B帧内部刷新越频繁，并且视频的图像质量可能会更好，但需要更多的帧在传输时进行编码和传输*/
    int         b_intra_refresh;    /* 周期性帧内刷新 Whether or not to use periodic intra refresh instead of IDR frames. */

    /*i_bframe参数用于控制B帧的数目。B帧指的是在一个视频序列中，位于I帧和P帧之间的预测帧。这些帧根据前后帧预测而来，并使用运动补偿技术来实现更好的视频压缩率和编码质量。i_bframe参数可以被用于指定B帧的数量，这对于压缩效率、视频质量和编码速度都有很大的影响。*/
    int         i_bframe;   /* how many b-frame between 2 references pictures */
    /*在x264编码器中，i_bframe_adaptive参数允许编码器动态地根据视频序列的复杂性调整B帧的数量，以适应不同的场景，提高视频质量并减少码率波动。

i_bframe_adaptive参数可以通过以下几种方式进行设置：

- i_bframe_adaptive=0：B帧数目恒定。
- i_bframe_adaptive=1：B帧数目根据视频序列中的动态变化进行调整。
- i_bframe_adaptive=2：B帧数量与i_bframe参数保持一致，但是不是固定数量的B帧，可能在处理场景变化时进行调整。

当i_bframe_adaptive=1时，编码器将根据视频序列中的场景变化和过渡情况，动态地调整B帧的数量。编码器首先计算每个宏块的SAD（Sum-of-Absolute-Differences）值，并根据场景变化的程度和SAD值进行决策。如果场景发生了变化，编码器会降低B帧的数量，以确保视频质量的稳定性。如果场景未发生变化，则编码器可以增加B帧的数量，以提高视频质量和压缩性能。 i_bframe_adaptive参数可以帮助编码器获得更好的视觉效果以及压缩率。*/
    int         i_bframe_adaptive;
    /*在x264编码器中，i_bframe_bias参数可用于改变参考帧之间的权重以减小码率波动或提高编码速度，而不会对视频质量造成明显的影响。B帧偏差，或B帧权重，可以通过调整i_bframe_bias参数值实现。

i_bframe_bias参数控制P和B参考帧的权重分布，可以用来调整B帧和P帧的相对权重，例如：设置i_bframe_bias=0时，可以将所有P帧与所有B帧同等地对待，而设置i_bframe_bias=1时，则倾向于将P帧作为参考帧，减少B帧的数量。在实际应用中，可以根据视频的特点来优化i_bframe_bias参数的设置，以实现最佳的视频编码。*/
    int         i_bframe_bias;
    /*在x264编码器中，i_bframe_pyramid参数指定是否使用B帧金字塔模式。B帧金字塔模式是一种在视频压缩期间引入额外的参考帧以提高视频质量的技术。这种技术可以让B帧的引用模式与P帧相似，从而在重新解码时减少运算量，提高解码的速度和效果，同时还可以减少码率的波动。

当i_bframe_pyramid=0时，编码器将关闭B帧金字塔模式，只使用普通的B帧引用结构。当i_bframe_pyramid=1时，编码器将打开B帧金字塔模式，使用更精细的B帧引用结构。

使用i_bframe_pyramid参数可以有效地减少码率波动，提高视频质量和解码性能，但是在编码的过程中会增加一定的计算量和带宽占用。在了解视频内容和压缩效率的情况下，可以根据需求进行调整。*/
    int         i_bframe_pyramid;   /* Keep some B-frames as references: 0=off, 1=strict hierarchical, 2=normal */
    // 在x264编码器中，b_open_gop参数用于启用或禁用开放式组 (Open GOP) 设置。Open GOP指的是视频图像组里的I帧与前面最近的的I帧不在同一个GOP中，也就是说前面有B帧或P帧预测得到了当前I帧的图像
    int         b_open_gop;
    // b_bluray_compat表示启用或禁用蓝光兼容模式。启用该模式时，编码器将遵循蓝光格式的规范，如最大码率、最大帧大小等，以确保编码输出与蓝光光盘兼容。禁用该模式时，则可以自由设置码率、分辨率等参数。
    int         b_bluray_compat;
    /*i_avcintra_class 是 AVC-Intra 视频编解码器的类别，是 Panasonic 公司开发的一种高清视频编解码器。i_avcintra_class 的取值范围为 50 和 100，分别表示 AVC-Intra 50 和 AVC-Intra 100 两种不同的编码规格。在 AVC-Intra 编码中，每个帧都独立压缩，比如每个 I 帧和 P 帧都是内部编码的，因此该编码器被称为无损压缩器。使用 i_avcintra_class 指定 AVC-Intra 编码器的参数可以获得更高的视频质量。在 x264 中，i_avcintra_class 是 x264_param_t 结构体中的一个参数，它可以设置为 50 或 100，以指定 AVC-Intra 规格的编码器类型。*/
    int         i_avcintra_class;
    /*x264中的 i_avcintra_flavor 是一种用于设置 AVC-Intra 视频编解码器参数的选项。AVC-Intra 标准涵盖多种不同的编码配置，每个配置都具有不同的参数值范围和编码质量。 i_avcintra_flavor 用于指定所需的编码器配置。x264中的 i_avcintra_flavor 支持以下几种编码器配置：

- AVC-Intra 50: 基于 H.264/MPEG-4 AVC 标准，采用 50 Mbps 的比特率，在主播放码流（PSP）模式下实现 1920x1080 或 1280x720 分辨率的视频编码。
- AVC-Intra 100: 基于 H.264/MPEG-4 AVC 标准，采用 100 Mbps 的比特率，在主播放码流（PSP）模式下实现 1920x1080 或 1280x720 分辨率的视频编码。
- AVC-Intra 50i: 基于现场生产生产（LSE）模式下的 H.264/MPEG-4 AVC 标准制定，支持 1440x1080 分辨率的交错编码。
- AVC-Intra 100i: 基于现场生产生产（LSE）模式下的 H.264/MPEG-4 AVC 标准制定，支持 1440x1080 分辨率的交错编码。

i_avcintra_flavor 可以通过设置 x264_param_t 中的 i_avcintra_flavor 参数来指定所需的编码器配置，以便进行视频编码。*/
    int         i_avcintra_flavor;

    // b_deblocking_filter 是 x264 中的一个参数，用于控制是否启用帧内环路滤波器（deblocking filter）。帧内环路滤波器是一种用于减少压缩视频中帧间伪影的技术，它可以通过在编码过程中进行滤波来平滑参考帧和当前帧之间的边界。b_deblocking_filter 参数默认值为 1，表示启用帧内环路滤波器，可以提高视频压缩的效果和图像质量。如果将 b_deblocking_filter 参数设置为 0，则会禁用帧内环路滤波器，从而使视频压缩的速度加快，但可能会降低视频质量并出现一些压缩伪影。因此，在运用上需要权衡速度和质量需要选择合适的值。
    int         b_deblocking_filter;
    // i_deblocking_filter_alphac0 是 x264 中的一个参数，代表帧内环路滤波器的 Alpha 值，即控制帧内滤波器使用的锐化程度。该参数的默认值为 0，表示使用 x264 自己内部的计算公式计算 Alpha 值。通常来说，修改 i_deblocking_filter_alphac0 值可以实现更细粒度的控制，从而得到更好的视频质量。如果要增强更强的边缘锐化效果，可以提高该值，而较小值则可以减少视频出现滤波产生的伪影效果，但也可能导致图像柔和。i_deblocking_filter_alphac0 一般需要和 i_deblocking_filter_beta_offset 这个参数配合使用，来控制滤波器的强度和平滑程度，这会对视频质量产生很大的影响。
    int         i_deblocking_filter_alphac0;    /* [-6, 6] -6 light filter, 6 strong */
    /*i_deblocking_filter_beta 是 x264 中的一个参数，代表帧内环路滤波器的 Beta 值，即控制帧内滤波器使用的平滑程度。该参数的默认值为 0，表示使用 x264 自己内部的计算公式计算 Beta 值。通常来说，修改 i_deblocking_filter_beta 值可以实现更细粒度的控制，从而得到更好的视频质量。如果要减少视频出现滤波产生的伪影效果，可以降低该值，而较大值则可以使图像更平滑。i_deblocking_filter_beta 一般需要和 i_deblocking_filter_beta_offset 这个参数配合使用，来控制滤波器的强度和平滑程度，这会对视频质量产生很大的影响。*/
    int         i_deblocking_filter_beta;       /* [-6, 6]  idem */

    /*b_cabac 是 x264 中的一个参数，用于启用或禁用 CABAC（Context Adaptive Binary Arithmetic Coding，上下文自适应二进制算术编码）模式。CABAC 是 H.264/AVC 标准中的一种压缩算法，它可以将视频数据通过自适应二进制算术编码的方式进行压缩，并同时保持原始图像质量。b_cabac 参数默认值为 1，表示启用 CABAC 模式，可以提高视频的压缩效果和质量。如果将 b_cabac 参数设置为 0，则会禁用 CABAC 模式，从而使视频压缩的速度加快，但可能会降低视频质量并出现一些压缩伪影。通常情况下，启用 CABAC 模式可以获得更好的压缩质量，但也会导致编码速度相对较慢。如果要求编码速度较快，则可以禁用 CABAC 模式。*/
    int         b_cabac;
    /*i_cabac_init_idc 是 x264 中的一个参数，用于设置 CABAC（Context Adaptive Binary Arithmetic Coding，上下文自适应二进制算术编码）编码器中的初始概率模型。CABAC 是一种压缩算法，它可以将视频数据通过自适应二进制算术编码的方式进行压缩，并同时保持原始图像质量。i_cabac_init_idc 的默认值为 0，这代表使用标准 H.264/AVC 的初始概率模型作为 CABAC 的初始值。此外，i_cabac_init_idc 参数的有效取值范围为 0 到 2 之间的整数值。具体来说，i_cabac_init_idc 等于 0 表示使用标准概率模型，等于 1 表示使用自定义的概率模型，等于 2 表示使用自定义概率模型，并且每个语法元素都有自己的概率模型。在使用 x264 进行编码时，可以将 i_cabac_init_idc 参数设置为适当的值，以获得更好的压缩效果和图像质量。*/
    int         i_cabac_init_idc;

    /*b_interlaced 是 x264 中的一个参数，用于控制编码器的帧间编码模式，即是否启用交错编码模式。b_interlaced 参数的默认值为 0，表示禁用交错编码模式，即按照逐行扫描的顺序依次编码每一行像素。如果将 b_interlaced 参数设置为 1，则启用交错编码模式，编码器将按照交替扫描的方式对一帧进行编码。交错编码模式通常用于编码交错扫描的视频，例如标准定义的 1080i 和 720i 视频格式。启用交错编码模式可以提高编码图像的清晰度和锐利度，但也会增加编码处理的时间和复杂度。在选择是否启用 b_interlaced 参数时，需要根据需要平衡编码速度和图像质量的要求。*/
    int         b_interlaced;
    /*b_constrained_intra 是 x264 中的一个参数，用于控制是否启用帧内限制模式。b_constrained_intra 参数的默认值为 0，表示禁用帧内限制模式。在帧内限制模式下，编码器会限制帧内预测的像素值只基于之前编码的图像数据，而不使用之后的数据。这可以提高压缩效率，减少码流，但也可能导致图像失真。启用 b_constrained_intra 参数可以保证在帧内预测时只使用之前的数据，从而减少编码器的复杂度，并且保证编码后的视频数据可以在不需要后续图像数据的情况下进行解码和播放。如果需要保证编码器的压缩效率和图像质量，并且不需要后续的图像数据，则可以启用 b_constrained_intra 参数。*/
    int         b_constrained_intra;

    /*i_cqm_preset 是 x264 中的一个参数，用于指定量化矩阵的预设值。量化矩阵是视频编码中重要的参数之一，用于控制编码的清晰度、压缩比、色彩饱和度等属性。i_cqm_preset 参数预置了一些常用的矩阵，包括 flat、jvt、h264、high、hq、lowdelay 和 placebo 等等。i_cqm_preset 的默认值为 -1，表示不使用预设的量化矩阵。设置 i_cqm_preset 的值只有在使用自定义量化矩阵（即不使用 x264 自带的默认量化矩阵）时才有意义。使用预设的量化矩阵可以方便用户选择合适的编码参数来满足不同的需求，例如高比特率下的高画质编码，或低比特率下的低延迟编码等等。如果需要自定义量化矩阵，可以使用 x264 自带的工具 x264_quantizer.pl 来生成自己的量化矩阵，并将其传递给 x264 编码器来使用。*/
    int         i_cqm_preset;
    /*psz_cqm_file 是 x264 中的一个参数，用于指定自定义量化矩阵所在的文件名。量化矩阵是视频编码中重要的参数之一，用于控制编码的清晰度、压缩比、色彩饱和度等属性。如果 psz_cqm_file 参数被设置为一个文件名，则 x264 编码器将从该文件中读取自定义的量化矩阵。psz_cqm_file 默认值为 NULL，表示不使用自定义的量化矩阵，而使用 x264 自带的默认量化矩阵。在使用自定义量化矩阵时，需要注意量化矩阵的数据格式和编码规范，以确保编码器能够正确地读取和应用矩阵数据。如果需要使用自定义量化矩阵，则应将其保存为一个文本文件，并将文件名传递给 psz_cqm_file 参数。*/
    char        *psz_cqm_file;      /* filename (in UTF-8) of CQM file, JM format */

    /*x264_param_t 中的 cqm_4iy 是一个大小为16的整型数组，存储了自定义量化矩阵，用于 I 帧中 4x4 宏块的量化参数设置。cqm_4iy 是 x264_param_t 结构体中的一个参数，可以用于自定义 H.264/AVC 视频编码标准中的量化矩阵，以实现更好的编码质量和压缩效率。x264 中定义了多种类型的量化矩阵，包括了预设的量化模板，用户也可以通过 cqm_4iy 参数手动设置自定义的量化矩阵参数。在使用自定义量化矩阵时，需要注意量化矩阵的数据格式和编码规范，以确保编码器能够正确地读取和应用矩阵数据*/
    uint8_t     cqm_4iy[16];        /* used only if i_cqm_preset == X264_CQM_CUSTOM */
    // 用于P帧？
    uint8_t     cqm_4py[16];
    // 色度
    uint8_t     cqm_4ic[16];
    uint8_t     cqm_4pc[16];
    // 8x8 I帧 亮度
    uint8_t     cqm_8iy[64];
    uint8_t     cqm_8py[64];
    uint8_t     cqm_8ic[64];
    uint8_t     cqm_8pc[64];

    /* Log */
    void        (*pf_log)( void *, int i_level, const char *psz, va_list );
    void        *p_log_private;
    int         i_log_level;
    // b_full_recon是x264的一个参数，可设置是否启用全样本互动(AVS2)或完整重建。当b_full_recon设置为true时，x264将使用全样本互动或完整重建模式进行编码，以提高编码效率。这种模式会增加编码时间和计算负担，但可以对编码效率产生明显的改善。如果编码的速度对你来说很重要，则可以将b_full_recon设置为false，以减少编码时间和计算负担。
    int         b_full_recon;   /* fully reconstruct frames, even when not necessary for encoding.  Implied by psz_dump_yuv */
    // psz_dump_yuv是x264的一个参数，用于设置编码器在编码过程中输出的yuv视频数据的文件名。如果指定了psz_dump_yuv参数，则编码器将在编码的每一帧结束时将其输出到指定的文件中。这个选项为调试和诊断提供了方便，可以帮助用户了解编码器的工作原理，比如检查帧率、分辨率或者颜色格式等。如果不需要这个调试功能，则可以忽略这个参数。
    char        *psz_dump_yuv;  /* filename (in UTF-8) for reconstructed frames */

    /* Encoder analyser parameters */
    struct
    {
        /*intra的值可以是以下三种之一：

- X264_INTRA_REFRESH_NONE：不使用intra帧刷新技术，也就是说不使用关键帧。
- X264_INTRA_REFRESH_CRA：使用CRA（clean random access）关键帧刷新技术，保证在一个GOP（group of pictures）内的所有帧都能被解码。
- X264_INTRA_REFRESH_IDR：使用IDR（instantaneous decoder refresh）关键帧刷新技术，保证在任何时候都能被解码。在IDR帧之前的所有GOP都无法被解码，因此在关键帧之间需要一定的间隔，以确保解码器在丢失帧之后可以尽快恢复。*/
        unsigned int intra;     /* intra partitions */
        /*而其中的inter变量用于设置编码中的预测类型（prediction mode）。

inter的值可以是以下三种之一：

- X264_INTER_NONE：不使用预测编码技术。
- X264_INTER_P：使用P帧预测编码技术。P帧是基于之前的帧（通常是关键帧和I帧）预测当前帧的方法，因此通常用于视频序列中的普通帧。
- X264_INTER_B：使用B帧预测编码技术。B帧是基于之前的帧和之后的帧预测当前帧的方法，因此通常用于视频序列中的高运动帧。

inter预测类型的选择会影响图像的质量、编码效率和延迟等参数，因此需要根据不同的应用场景进行选择。*/
        unsigned int inter;     /* inter partitions */

        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的b_transform_8x8变量用于设置B帧的8x8变换模式。

在B帧的编码过程中，需要对8x8块进行DCT/IDCT变换，以适应不同场景下复杂度的视频信号。在x264编码器中，b_transform_8x8可以设置为以下三种取值之一：

- X264_B_ADAPT_TRELLIS：开启8x8的变换模式，并启用可遍历算法（Trellis）优化8x8块的编码效率和质量。
- X264_B_DCT_ONLY：仅使用4x4的变换模式，不使用8x8的变换模式。
- X264_B_ALLOW_8X8：开启8x8的变换模式，但不启用Trellis算法。

b_transform_8x8的选择会影响编码时块的变换过程，进而影响B帧编码的效率和画质等参数。新版本的x264编码器默认情况下会开启8x8变换模式，以提高编码效率和图像质量。*/
        int          b_transform_8x8;
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_weighted_pred变量用于设置I帧加权预测模式。

i_weighted_pred的取值可以是以下三种之一：

- X264_WEIGHTP_NONE：不进行加权预测，即不使用加权预测模式。
- X264_WEIGHTP_SIMPLE：使用简单的加权预测模式。简单加权预测仅基于参考帧的权重系数，对I帧进行预测。
- X264_WEIGHTP_YES：使用复杂的加权预测模式。会根据参考帧的权重系数和位置因素，对I帧进行预测。

加权预测可以提高编码效率和图像质量，在一些应用场景下可以取得比普通预测更好的编码效果。i_weighted_pred的选择需要根据应用场景和实际需求来评估。*/
        int          i_weighted_pred; /* weighting for P-frames */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的b_weighted_bipred变量用于设置B帧加权双向预测模式。

b_weighted_bipred的取值可以是以下三种之一：

- X264_B_ADAPT_NONE：不使用加权双向预测模式。
- X264_B_ADAPT_FAST：使用简单的加权双向预测模式，只基于参考帧的权重系数，对B帧进行预测。
- X264_B_ADAPT_TRELLIS：使用复杂的加权双向预测模式，对B帧进行预测，并启用可遍历算法（Trellis）来优化编码效率和质量。

加权双向预测可以提高B帧的编码效率和图像质量，在一些高运动场景下具有很好的效果。b_weighted_bipred的选择需要根据应用场景和实际需求来评估，选择不同的加权双向预测模式会影响编码效果和编码速度。*/
        int          b_weighted_bipred; /* implicit weighting for B-frames */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_direct_mv_pred变量是一个开关参数，用于设置直接运动矢量预测模式。

i_direct_mv_pred的取值可以是以下两种之一：

- X264_DIRECT_PRED_NONE：不启用直接运动矢量预测模式。
- X264_DIRECT_PRED_AUTO：启用直接运动矢量预测模式并自适应选择使用该模式的时机。

直接运动矢量预测模式允许运动矢量在两个相邻块之间直接进行预测而不需要计算它们之间的差异。这可以减少运动估计所需的计算，从而提高编码效率和速度。开启i_direct_mv_pred选项可以加速编码器的速度，并且在某些视频场景下也可能得到更好的压缩效果。默认情况下，该开关被设置为X264_DIRECT_PRED_AUTO。*/
        int          i_direct_mv_pred; /* spatial vs temporal mv prediction */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_chroma_qp_offset变量是用于设置色度QP偏移量的参数。

QP（Quantization Parameter）是压缩视频时用于控制图像质量和比特率的重要参数。色度QP偏移量用于调整色度信号的量化步长，以便更精确地控制色度信号的压缩质量。i_chroma_qp_offset用于设置色度QP偏移量的值，即色度信号相对于亮度信号的QP偏移量。

默认情况下，i_chroma_qp_offset被设置为0，也就是亮度信号和色度信号具有相同的QP值。如果设置为正数，则色度信号将比亮度信号具有更高的QP值，这将减少色度信号的压缩比率，从而提高色度信息的精度和质量。如果设置为负数，则色度信号将比亮度信号具有更低的QP值，这将增加色度信号的压缩比率，从而降低色度信息的精度和质量。*/
        int          i_chroma_qp_offset;

        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_me_method变量是用于设置运动估计（Motion Estimation）方法的参数。

i_me_method的取值可以是以下三种之一：

- X264_ME_DIA：使用钻石搜索法（Diamond Search）进行运动估计。这是一种简单且计算量较小的运动估计方法，适用于低码率场景。
- X264_ME_HEX：使用六边形搜索法（Hexagon Search）进行运动估计。这种方法可以更准确地估计大范围运动，适用于高码率场景。
- X264_ME_UMH：使用渐进多级搜索法（Uneven Multi-Hexagon）进行运动估计。这种方法在精度和速度之间提供了一种权衡，适用于码率和解码复杂度都比较高的场景。

不同的运动估计方法选择会影响编码效率和画质等参数，需要根据实际应用场景选择最适合的方法。默认情况下，i_me_method被设置为X264_ME_HEX。*/
        int          i_me_method; /* motion estimation algorithm to use (X264_ME_*) */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_me_range变量是用于设置运动估计（Motion Estimation）的搜索范围大小。

i_me_range的取值可以是1到任何正整数。该参数表示在搜索运动矢量时帧间像素块的搜索范围大小，以像素为单位。在搜索运动矢量时，x264编码器使用块大小为16x16像素，并在一个块周围的搜索范围内搜索匹配项，以找到给定块的最佳运动矢量。

较大的搜索范围可以找到更好的匹配块，并提高编码质量，但会增加编码时间和复杂度。较小的搜索范围可以减少编码时间和复杂度，但可能会导致编码质量下降。默认情况下，i_me_range被设置为16，这个值可以根据视频场景和所需的速度和精度进行调整。*/
        int          i_me_range; /* integer pixel motion estimation search range (from predicted mv) */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_mv_range变量是用于限制运动矢量（Motion Vector）的范围大小的参数。

i_mv_range的取值可以是1到任何正整数。该参数应该设置为在编码时可能出现的最大运动补偿范围加1的值，以像素为单位。当运动矢量的位移量超出了所设定的范围时，x264编码器将对其进行限制处理。通过限制能够表示的最大运动范围，可以控制编码的码率并减少运动矢量带来的编码复杂度。

较小的值会限制运动矢量的位移范围，这可能会降低编码的时延和码率，但也可能导致编码质量下降。较大的值将允许更大的位移，从而可能导致更好的编码质量，但也可能增加编码复杂度和码率。 默认情况下，i_mv_range被设置为16。*/
        int          i_mv_range; /* maximum length of a mv (in pixels). -1 = auto, based on level */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_mv_range_thread变量用于设置多线程中运动矢量搜索范围大小的参数。

i_mv_range_thread的取值可以是1到任何正整数。该参数控制x264编码器在使用多线程时，对每个线程分配不同的运动矢量搜索范围的大小。如果设置为1，则所有线程都将使用相同的搜索范围。如果设置为大于1的值，则可以根据处理器内核数为不同的线程设置不同的搜索范围大小，以优化多线程性能。

通过使用不同的搜索范围大小，每个线程可以在不同的部分搜索最佳运动矢量，从而加速整个编码过程。较小的搜索范围可以减少搜索时间和复杂度，但也会影响编码效率和质量。较大的搜索范围可以提高编码效率和质量，但也会增加计算时间和复杂度。默认情况下，i_mv_range_thread被设置为0，表示使用与i_mv_range相同的范围大小。*/
        int          i_mv_range_thread; /* minimum space between threads. -1 = auto, based on number of threads. */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的i_subpel_refine参数用于设置亚像素级（Subpixel）运动估计的精度。

i_subpel_refine的取值可以是0-11之前的值，貌似只有0有比较明确的意义，只能代码怎么写就怎么看。。：

- 0：禁用亚像素级别的运动估计，只使用整像素级别的运动估计。
- 1：启用亚像素级别的运动估计。这种方法通过对所选定的最佳匹配像素块进行进一步的亚像素级别的移动和计算，以提高运动矢量估计的精度和图像的压缩效果。
- 2：亚像素精度2
- 3：>=3时，b_try_skip = 1;
- 4：精度4
- 6：亚像素质量6，p帧时，大于该值可以色度运动估计；i_mbrd：为1
- 8：质量8
- 9：质量9，b帧时，大于该值可以色度运动估计；rdo支持滤波；i_mbrd为2
- 10：质量10，i_mbrd为3；
- 11：质量11，a->b_early_terminate=0；
i_subpel_refine的选择取决于应用场景和实际需求，启用亚像素级别的运动估计可以提高运动估计的精度和图像质量，但也会增加编码时间和计算复杂度。*/
        int          i_subpel_refine; /* subpixel motion estimation quality */
        /*在x264编码器中，x264_param_t是编码器参数的结构体。而其中的b_chroma_me变量用于开启或关闭色度分量的运动估计。

b_chroma_me的取值可以是以下两种之一：

- 0：禁用色度分量的运动估计。
- 1：启用色度分量的运动估计。

开启色度分量的运动估计可以提高编码质量，因为在色度空间中也存在运动，而只考虑亮度分量的运动估计不足以捕捉到全部的运动信息。但是，开启色度分量的运动估计会增加编码的CPU复杂度和计算量。默认情况下，b_chroma_me被设置为1，即开启色度分量的运动估计。*/
        int          b_chroma_me; /* chroma ME for subpel and mode decision in P-frames */
        /*x264_param_t中的b_mixed_references是一个布尔值，用于控制在编码过程中是否允许混合参考帧。如果设置为1，则允许混合参考帧，即参考帧可以来自不同的图像层。如果设置为0，则不允许混合参考帧，参考帧必须来自同一图像层。混合参考帧可以提高编码效率，但可能会影响编码质量。*/
        int          b_mixed_references; /* allow each mb partition to have its own reference number */
        /*i_trellis是x264_param_t中控制trellis量化和反量化（Trellis Quantization and Dequantization）的变量。Trellis Quantization和Dequantization是一种优化码率和图像质量的技术，通过在量化和反量化过程中引入额外的复杂度来提高编码效率和图像质量。

i_trellis变量的可选值为0、1、2、3，它们分别表示不使用trellis量化/反量化、使用trellis量化/反量化（默认值）、使用trellis量化/反量化并且在非I帧中使用更小的代价矩阵、使用trellis量化/反量化并且在所有帧中使用更小的代价矩阵。在编码过程中，i_trellis的值越大，trellis量化/反量化的复杂度就越高，但可能会显著提高编码效率和图像质量。*/
        int          i_trellis;  /* trellis RD quantization */
        
        /*x264_param_t中的b_fast_pskip是一个布尔参数，在x264编码器中用于控制快速P帧跳过模式。快速P帧跳过模式是一种跳过部分P帧预测模式的技术，通过减少P帧的计算量，达到提升编码速度的目的，同时也会有一定的影响编码效果。具体来说，b_fast_pskip参数可以取以下两个值：

- 0：表示不使用快速P帧跳过模式，编码器将对每个P帧采用完整的预测模式计算，使编码效果更好，但是编码速度会变慢。

- 1：表示启用快速P帧跳过模式，编码器将跳过部分P帧预测模式的计算过程，以加快编码速度。但是这样会影响编码效果，即视频质量会相应下降。

综上所述，b_fast_pskip参数能够在编码速度和编码效果之间寻找一个平衡点，根据实际需求来使用。*/
        int          b_fast_pskip; /* early SKIP detection on P-frames */
        /*b_dct_decimate是x264_param_t中的一个布尔参数，用于控制快速DCT降采样模式（Fast DCT Decimation）的开启和关闭。DCT降采样是x264编码器中的一种技术，可以通过去掉DCT变换后的高频分量，缩小视频帧的尺寸，降低数据冗余，从而提高编码效率。而快速DCT降采样模式则进一步加快了这个过程。

具体来说，当b_dct_decimate参数打开时，编码器快速对DCT系数进行降采样，来获得一个更加紧凑的DCT域表示。这样可以减少DCT系数的数量，降低编码复杂度和码率。

然而，b_dct_decimate降采样也可能导致图像的失真，特别是对于较低的码率和分辨率。因此，打开或关闭b_dct_decimate参数应该根据实际情况和需求进行权衡和选择。*/
        int          b_dct_decimate; /* transform coefficient thresholding on P-frames */
        /*i_noise_reduction是x264_param_t中的一个整型参数，用于控制编码器中的噪声抑制处理。噪声抑制处理旨在在编码过程中去除视频中的噪声和杂色，从而提高编码质量和视觉感受性。

具体来说，i_noise_reduction参数取值范围是0到100，表示噪声抑制强度的程度。数值越大，噪声抑制处理越强，图像中的噪声和杂色也就越少，但同时可能会降低图像的锐度及其细节层次。参数取值为0时，表示禁用噪声抑制处理。

需要注意的是，启用i_noise_reduction参数会增加编码复杂度，从而影响编码速度。i_noise_reduction参数的设置应该根据实际情况进行平衡，以便在提高编码质量的同时保持适当的编码速度。*/
        int          i_noise_reduction; /* adaptive pseudo-deadzone */
        /*f_psy_rd是x264_param_t中的一个浮点数参数，用于控制视觉感知优化的相关参数。视觉感知优化是x264编码器中的一种技术，可以根据人眼视觉系统的特点，对视频编码过程进行优化，提高视觉质量和编码效率。

具体来说，f_psy_rd参数表示视觉感知优化时的最大可接受失真水平，对于高于该水平的失真，编码器会尽可能地进行更加精确的编码，以达到更高的视觉质量。

f_psy_rd通常与f_psy_rdo（视觉感知优化时使用的码率推导方法）一起使用，以平衡视觉质量和码率之间的关系。

需要注意的是，f_psy_rd参数的增大或减小可能会对编码速度和码率产生影响，应该在具体应用中进行平衡和调整。*/
        float        f_psy_rd; /* Psy RD strength */
        /*f_psy_trellis是x264_param_t中的一个浮点数参数，用于控制视觉感知优化中的trellis量化。Trellis量化是x264编码器中的一种技术，旨在通过优化量化过程中的分段分配来提高编码效率和视觉质量。

具体来说，f_psy_trellis参数控制Trellis量化在编码过程中的影响程度。参数取值越大，Trellis量化的影响就越大，从而可能提高编码质量，但同时也可能增大编码时间。相反，参数取值越小，Trellis量化的影响就越小，编码时间也会相应减小，但可能会影响编码效果。

需要注意的是，f_psy_trellis参数只对psy-RD功能打开时有效，它可以与其他相关的参数（如f_psy_rd、f_psy_rdo等）一起使用，以实现最佳的视觉效果和编码速度。在使用时，应根据实际需求进行平衡和调整。*/
        float        f_psy_trellis; /* Psy trellis strength */
        /*b_psy是x264_param_t中的一个布尔参数，用于控制x264的视频编码器是否启用视觉感知优化。视觉感知优化是一种优化算法，可以使x264评估图像的质量和视觉感受，通过调整码率-失真曲线，在最小化失真的同时最大化图像质量。

启用b_psy参数后，编码器将基于psy-RD算法对视频进行编码。Psy-RD功能是一种基于视觉响应的优化算法，通过对人眼对不同空间和时间范围内的图像细节的感知特性进行建模，可以更好地处理编码过程中的失真，提高视频编码的质量和效率。

需要注意的是，启用b_psy将会增加编码器的计算和处理负担，导致编码速度减慢。如果需要在编码速度和视频质量之间进行权衡，应该根据实际应用场景和需求来选择是否启用b_psy参数。*/
        int          b_psy; /* Toggle all psy optimizations */

        /*b_mb_info是x264_param_t中的一个布尔参数，用于控制x264编码器是否输出宏块信息。宏块是编码器和解码器中的基本单元，宏块的大小通常是16x16像素，整张视频帧由不同数量的宏块组成。

启用b_mb_info参数后，x264编码器将会为每个宏块输出额外的信息，包括宏块的位置、类型、是否有运动矢量等等。这些宏块信息对于视频数据分析、压缩算法优化等方面都有很大的帮助，同时还可以用于视频监控、视频分析等应用场景之中。

需要注意的是，启用b_mb_info参数会增加编码器的计算量和数据量，从而可能会导致编码速度的降低和码流大小的增加。因此，在实际应用中需要根据具体情况进行考虑和权衡。*/
        int          b_mb_info;            /* Use input mb_info data in x264_picture_t */
        /*b_mb_info_update是x264_param_t中的一个布尔参数，用于控制x264编码器是否在P帧中输出宏块信息的更新。b_mb_info_update参数只在b_mb_info参数打开的情况下才能生效。

启用b_mb_info_update参数后，编码器将在每个P帧中输出宏块信息的更新，这样可以减小编码器的数据输出量，同时还能够更好地控制输出信息的实时性和精准性。

需要注意的是，启用b_mb_info_update参数会增加编码器的计算量和数据量，从而可能会导致编码速度的降低和码流大小的增加。因此，在实际应用中需要根据具体情况进行考虑和权衡。同时，如果应用场景中不需要实时更新宏块信息，则可以将b_mb_info_update参数关闭。*/
        int          b_mb_info_update; /* Update the values in mb_info according to the results of encoding. */

        /*i_luma_deadzone是x264_param_t中的一个整型参数，用于控制亮度死区值（Luma Deadzone）。亮度死区值是在编码过程中用来控制亮度变化的范围，即将亮度值超过一定范围的像素映射到同一级别上，从而减少不必要的细节信息，提高编码效率。

具体来说，i_luma_deadzone参数指定了一组值，表示在编码过程中将亮度值映射到同一级别上的范围。参数取值越大，亮度映射的范围就越大，可以减少更多的细节信息，从而提高编码效率，同时也可能导致图像质量的降低。相反，参数取值较小则能够保留更多的细节信息和亮度变化，从而提高图像质量，但同时也会降低编码效率。

需要注意的是，适当调节i_luma_deadzone参数可以在编码速度和编码质量之间取得一个平衡点。在具体应用中，根据需要进行平衡和调整，以获得最佳编码效果。*/
        /* the deadzone size that will be used in luma quantization */
        int          i_luma_deadzone[2]; /* {inter, intra} */

        /*b_psnr是x264_param_t中的一个布尔参数，用于控制编码器在编码时是否输出PSNR信息。PSNR（Peak Signal-to-Noise Ratio）是一种常用的评估视频编码质量的指标，它能测量编码后的视频与原始视频之间的失真程度。

启用b_psnr参数后，编码器将在编码过程中输出PSNR和其他相关信息，包括原始视频帧和编码后的视频帧之间的误差、平均PSNR值、帧间PSNR值等等。这些信息对于评估编码质量和视频比较非常有用。

需要注意的是，启用b_psnr参数会增加编码器的计算量和输出量，从而可能会导致编码速度的降低和编码时间的增加。在实际应用中需要根据具体情况进行权衡和调节。*/
        int          b_psnr;    /* compute and print PSNR stats */
        /*b_ssim是x264_param_t中的一个布尔参数，用于控制编码器在编码时是否输出SSIM信息。SSIM（Structural SIMilarity index）是一种用于评估图像质量的指标，可以衡量编码后的视频与原始视频之间的相似度。

启用b_ssim参数后，编码器将在编码过程中输出SSIM和其他相关信息，包括原始视频帧和编码后的视频帧之间的差异、平均SSIM值、帧间SSIM值等等。这些信息对于评估编码质量和视频比较非常有用。与PSNR相比，虽然SSIM能更好评估宏块结构和图像细节的保留情况，但它的计算复杂度相对较高。

需要注意的是，启用b_ssim参数会增加编码器的计算量和输出量，从而可能会导致编码速度的降低和编码时间的增加。在实际应用中需要根据具体情况进行权衡和调节。*/
        int          b_ssim;    /* compute and print SSIM stats */
    } analyse;

    /* Rate control parameters */
    struct
    {
        /*x264_param_t中的i_rc_method是编码器采用的码率控制方式。具体来说，这个参数指定了编码器如何选择每帧的码率以达到所需的输出质量。可以设置为以下几种值：

- X264_RC_CQP：恒定质量模式。
- X264_RC_CRF：恒定质量模式，但平均比特率会随着宏块复杂度而变化。
- X264_RC_ABR：恒定比特率模式。
- X264_RC_VBR：可变比特率模式，可以在一定限定的码率范围内改变比特率以达到更高的画面质量。
- X264_RC_QP_MIN_MAX：通过控制QP的最大最小值保持视频的平均比特率在一个范围内。

不同的码率控制方式在各自的场景下有优缺点，需要根据实际需求来选择。*/
        int         i_rc_method;    /* X264_RC_* */

        /*i_qp_constant是x264_param_t结构体中的一个参数，用于设置恒定的QP偏移值。它表示的是在使用恒定QP模式时，编码器将在QP基础上添加的固定常量。这个常量的范围是[0, 69]，默认值为0。

QP值是视频编码中常用的概念，表示量化参数的大小。在x264中，QP值越大，视频质量越差，文件大小越小，反之亦然。i_qp_constant参数的作用类似于在QP基础上增加或减少一个常数，以调整视频质量和文件大小之间的平衡。

需要注意的是，使用恒定QP模式可能会导致视频在不同场景下的质量不稳定，因此一般建议使用恒定质量模式或者可变比特率模式。*/
        int         i_qp_constant;  /* 0=lossless */
        /*i_qp_min是x264_param_t结构体中的一个参数，用于设置编码器允许使用的最小QP值。QP值是视频编码中常用的概念，表示量化参数的大小。在x264中，QP值越大，视频质量越差，文件大小越小，反之亦然。

i_qp_min参数的默认值是0，表示编码器可以使用最小的QP值。但是，如果i_rc_method参数设置为X264_RC_ABR或X264_RC_VBR，则i_qp_min的值会被自动调整。

在使用i_rc_method参数设置为X264_RC_ABR或X264_RC_VBR时，x264编码器会尝试达到设定的平均比特率，而不是恒定的QP值或恒定的质量值。在这种情况下，i_qp_min参数实际上表示编码器在控制码率的同时所允许的最小质量保证，因为编码器可能在需要的情况下使QP达到i_qp_min的值，以保证视频质量不会过低。

需要注意的是，设置i_qp_min值过低或者太高都可能导致编码器效果不佳，因此一般建议根据实际需求进行调整。*/
        int         i_qp_min;       /* min allowed QP value */
        /*i_qp_max是x264_param_t结构体中的一个参数，用于设置编码器允许使用的最大QP值。QP值是视频编码中常用的概念，表示量化参数的大小。在x264中，QP值越大，视频质量越差，文件大小越小，反之亦然。

i_qp_max参数的默认值是69，表示编码器可以使用最大的QP值。但是，如果i_rc_method参数设置为X264_RC_ABR或X264_RC_VBR，则i_qp_max的值会被自动调整。

在使用i_rc_method参数设置为X264_RC_ABR或X264_RC_VBR时，x264编码器会尝试达到设定的平均比特率，而不是恒定的QP值或恒定的质量值。在这种情况下，i_qp_max参数实际上表示编码器在达到平均比特率的同时所允许的最高质量保证，因为编码器可能在需要的情况下使QP达到i_qp_max的值，以保证视频质量不会过高。

需要注意的是，设置i_qp_max值过低或者太高都可能导致编码器效果不佳，因此一般建议根据实际需求进行调整。*/
        int         i_qp_max;       /* max allowed QP value */
        /*i_qp_step是x264_param_t结构体中的一个参数，用于设置编码器在逐渐逼近最优QP值时的步长。QP值是视频编码中常用的概念，表示量化参数的大小。在x264中，QP值越大，视频质量越差，文件大小越小，反之亦然。

在x264编码器中，编码器会在编码每一帧时根据视频质量和目标比特率等因素来选择最优的QP值。i_qp_step参数表示编码器在寻找最优QP值的过程中所允许的最大QP变化值。默认值是4，表示编码器可以以4的步长来逼近最优QP值。如果i_qp_step的值设置过小，编码器将需要更多的时间和计算资源来寻找最优QP值，而如果设置过大，可能会影响视频的质量。

需要注意的是，i_qp_step参数只对使用恒定质量模式和恒定QP模式的编码器有效，对于使用其他码率控制模式的编码器而言，这个参数的作用不明显。*/
        int         i_qp_step;      /* max QP step between frames */

        /*i_bitrate是x264_param_t结构体中的一个参数，用于设置编码器的目标比特率，单位为比特每秒（bps）。比特率表示每秒钟传输的数据量，是衡量视频压缩质量的重要指标。较高的比特率可以提供更好的视频质量，但同时也会增加视频文件的大小。

如果使用i_rc_method设置为X264_RC_CRF或X264_RC_ABR，则i_bitrate参数不会起作用。如果使用的是恒定比特率控制X264_RC_BITRATE，则i_bitrate参数表示的是每秒输出的比特率。如果使用恒定质量X264_RC_CQP或X264_RC_VBR控制，则i_bitrate参数表示的是最大比特率值。

需要注意的是，i_bitrate 参数的值必须根据实际需求进行合理的设置。如果比特率设置得太低，会使视频的质量下降，太高会浪费存储空间。*/
        int         i_bitrate;

        /*f_rf_constant是x264_param_t结构体中的一个参数，用于设置CRF模式下的参考质量偏移量，用于对整个视频的量化水平进行调整，从而影响压缩后得到的视频质量。

CRF（Constant Rate Factor）是一种恒定质量控制模式，它会通过在压缩过程中固定目标质量因子的值，来自动调整比特率，以达到所需的输出质量。f_rf_constant参数表示的是在CRF控制模式下，编码器每一帧采用的量化参数与整体参考质量的偏移量。

f_rf_constant的默认值是0，表示不进行偏移。如果将此参数设置为正值，则会使得压缩的视频每一帧的量化参数偏轻，从而导致输出的视频质量更高。反之，如果设置为负值，则会使得压缩时的量化参数偏重，从而导致输出的视频质量更低。

需要注意的是，f_rf_constant参数只适用于CRF模式，不能与其他模式一起使用。此外，该参数应该根据视频编码的实际需要进行调整，不建议默认情况下修改该参数的值。*/
        float       f_rf_constant;  /* 1pass VBR, nominal QP */
        /*x264_param_t中的f_rf_constant_max是用于设置CRF控制模式下参考质量偏移量的最大值。参考质量偏移量(f_rf_constant)用于在每一帧的量化参数与整体参考质量之间进行调整，从而调节压缩率和压缩后视频的视觉质量。f_rf_constant_max参数的默认值是1.0，表示参考质量偏移量的最大值为1.0，也就是参考质量可以比整体质量轻1.0倍。

用户可以根据需要调整f_rf_constant_max参数的值。将参数的值减小会对参考质量的偏移量进行限制，从而始终保持良好的视觉质量，但会导致输出文件的大小增加。而将参数的值设为较高的值，则可以使参考质量比整体质量轻得更多，从而使输出文件的大小进一步减小，但可能会降低视频质量。建议根据实际情况进行调整，以达到最佳的输出效果。*/
        float       f_rf_constant_max;  /* In CRF mode, maximum CRF as caused by VBV */
        /*f_rate_tolerance是x264_param_t结构体中的一个参数，用于设置码率控制的容忍度。在可变码率控制模式下，编码器将自适应比特率，以尽可能地实现所设置的输出质量。f_rate_tolerance表示编码器调整码率的偏差容忍度，超出此范围的误差将被平滑处理。当实际码率与目标码率的误差小于等于f_rate_tolerance时，编码器将不对其进行调整。

f_rate_tolerance的默认值是1.0，表示误差容忍度为1.0。如果设置得太大，可能会导致码率变化过大，从而影响视频质量，同时输出的文件大小也会变得不均衡。如果设置得太小，则可能会导致过多的码率调整，从而增加编码时间。

需要注意的是，f_rate_tolerance参数只对使用了可变码率控制模式的编码器有效，如果需要更好的编码效果，建议使用可变质量模式或者恒定质量模式。*/
        float       f_rate_tolerance;
        /*i_vbv_max_bitrate是x264_param_t结构体中的一个参数，用于设置视频码流的最大瞬时比特率。VBV（Video Buffering Verifier）的比特率控制方式便是根据i_vbv_max_bitrate来约束压缩出来的视频码流在任意时刻的数据流速不超过设定的上限，从而防止视频播放时的卡顿和花屏。

在可变比特率控制模式下，编码器会根据视频内容的复杂程度和目标比特率等因素自适应地调整比特率。设置i_vbv_max_bitrate参数可以限制视频的瞬时峰值比特率，防止数据流速度过高导致的缓存溢出和质量下降。默认值为0，表示不进行限制。

需要注意的是，实际的压缩码率和数据带宽会根据视频内容和其他因素的影响而有所差异，因此i_vbv_max_bitrate的值应该根据实际需求进行调整。并且，如果未设置VBV缓冲区大小，则i_vbv_max_bitrate参数将不起作用。*/
        int         i_vbv_max_bitrate;
        /*i_vbv_buffer_size是x264_param_t结构体中的一个参数，用于设置VBV（Video Buffering Verifier）缓存区的大小，缓存区的单位通常是比特（bps），用于控制视频的比特率。

VBV缓存区是一个按比特率和缓存时间来支配码流输出的缓冲区，用于控制码率在容许范围内波动。在可变比特率（VBR）控制模式下，编码器会根据视频内容的复杂程度和目标比特率等因素自适应地调整比特率。设置i_vbv_buffer_size参数可以限制视频的平均比特率在给定的范围内。

i_vbv_buffer_size的默认值为0，表示不进行限制。如果设置了i_vbv_buffer_size的值，那么在编码输出的码流中就会包含VBV缓存区的设置，从而在解码时能够更加准确地控制码率输出。

需要注意的是，i_vbv_buffer_size参数的值应该根据实际需求进行调整，不能太小或太大。如果设置得太小，可能会导致数据流过低，从而影响视频质量和流畅度；如果设置得太大，可能会浪费存储空间并降低编码效率。*/
        int         i_vbv_buffer_size;
        /*在x264_param_t结构体中，f_vbv_buffer_init是一个表示VBV（Video Buffering Verifier）缓冲区初始大小的浮点型参数。VBV是用于控制输出码率和保证视频质量的重要参数，它为编码器提供了一个输出码率的参考值。在使用x264编码器时，可以通过设置f_vbv_buffer_init参数来调整VBV缓冲区大小。

一般来说，f_vbv_buffer_init的默认值是1.0，这意味着编码器将根据码率来调整VBV大小。如果需要更好的码率控制或更好的视频质量，可以根据具体需求调整f_vbv_buffer_init的大小。

举个例子，如果希望在固定码率下达到更好的视频质量，可以将f_vbv_buffer_init的值调小。这会减小VBV缓冲区的大小，意味着编码器会更严格地控制输出码率，从而能够提高视频的质量。

另一方面，如果希望在变化的码率下保持流畅的视频输出，可以将f_vbv_buffer_init的值调大。这会扩大VBV缓冲区的大小，使其能够存储更多的数据，在变化的码率情况下保持较为稳定的输出。

总之，f_vbv_buffer_init参数对于码率控制和视频质量非常重要，需要根据具体需求进行调整。*/
        float       f_vbv_buffer_init; /* <=1: fraction of buffer_size. >1: kbit */
        /*f_ip_factor参数在x264编码器中用于控制帧内编码的大小。在H264/AVC编码标准中，编码器可以使用帧内预测和帧间预测两种方式来压缩视频。帧内预测是在同一个视频序列中通过参考现有像素点来压缩当前帧的数据，同时保持视频质量。只要发现当前视频帧跟先前的帧相似，帧内预测就会自动启用。帧间预测则是在不同的视频序列中进行压缩，它通过分析参考帧和当前帧之间的像素值来减少数据。这两个预测方式的开销不同，编码器需要根据具体情况来确定使用哪种方式。

f_ip_factor参数的默认值是1.4。当这个值越大的时候，为了达到给定的码率，编码器会更多地使用帧间预测，而减少使用帧内预测。因为帧内预测的压缩效率要低于帧间预测，需要更多的比特数来表示同样的视频内容。相应地，当f_ip_factor参数的值越小的时候，编码器会更多地使用帧内预测，而减少使用帧间预测。因为帧内预测的压缩效率虽然低于帧间预测但是会保持视频的质量。

要调整f_ip_factor参数，需要根据具体应用场景的需要来判断。如果要在低码率下保持相对较好的视频质量，可以适当增大f_ip_factor的值。而如果不考虑码率而追求更好的视频质量，则可以适度降低f_ip_factor的值。

总之，f_ip_factor参数对于控制帧内预测和帧间预测的开销非常重要，需要根据应用场景中的需求进行调整。*/
        float       f_ip_factor;
        /*f_pb_factor是x264_param_t结构体中一个浮点型参数，用于控制帧间预测（P帧和B帧）的开销和编码效率。这个参数的默认值是1.3。

在H.264/AVC编码中，帧间预测是通过在当前帧中使用前面或者后面的已编码帧的数据来压缩当前帧的数据。P帧和B帧是两种不同的帧间预测方式，其中P帧是按时间顺序向前预测的帧，而B帧可以沿着时间轴向前或向后预测。这两种预测方式的开销不同，编码器需要根据具体情况来确定使用哪种方式。

f_pb_factor参数就是用来控制帧间预测的开销，通过调整它的大小，可以平衡输出比特率和视频质量之间的关系。例如，将f_pb_factor的值调小可以减少帧间预测的开销，从而减小码率，但可能会影响视频质量；反之，将f_pb_factor的值调大可以增加帧间预测的开销，提高视频质量，但可能会增加输出比特率。

总之，f_pb_factor参数对于控制编码输出的比特率和视频质量平衡十分重要，需要根据具体的应用需求进行调整。*/
        float       f_pb_factor;

        /* VBV filler: force CBR VBV and use filler bytes to ensure hard-CBR.
         * Implied by NAL-HRD CBR. */
        /*b_filler是x264_param_t结构体中的一个布尔值参数，用于控制编码器在视频序列中的B帧之间添加填充帧来提高视频压缩率和减少码率。该参数的默认值为false，即编码器不会打开这个功能。

在视频编码中，B帧的编码是在参考帧之前和之后都引用参考帧来完成，这使得B帧的编码比P帧更有效。不过如果B帧的滞后过大，随着时间的推移会使得参考帧变得过时，B帧的编码效果会变得不佳。为了解决这个问题，x264编码器提供了一个填充帧的功能，用来增加B帧的间隔，从而提高参考帧的有效性。

启用b_filler参数后，编码器会在B帧之间添加填充帧。填充帧实际上是一个特殊的B帧，它在解码时会被忽略，因此不会对质量产生影响。在添加填充帧的同时，编码器可以调整参考帧的间隔，从而使得B帧的参考帧更加适合之前的视频内容，提高编码效果。

需要注意的是，启用b_filler参数可以提高编码器的压缩效率和减少码率，但同时会增加编码的延迟。填充帧会引入额外的编码过程，因此会增加编码时间。

总之，b_filler参数是一个控制编码器在视频序列中添加填充帧的参数。启用它可以提高视频压缩率和减少码率，但同时也会增加编码延迟。*/
        int         b_filler;

        /*i_aq_mode是x264编码器中的参数之一，用于控制自适应量化模式（Adaptive Quantization Mode）的设置。自适应量化模式可以根据帧间的运动信息来调整量化系数，从而在保证图像质量的前提下，进一步减小码流大小。i_aq_mode共有4种模式可选，包括AQ_DISABLED（不使用自适应量化模式）、AQ_LIVE（适用于实时流媒体场景）、AQ_AUTO（适用于大部分场景）、AQ_GENERIC（适用于可变帧率或掉帧情况）。*/
        int         i_aq_mode;      /* psy adaptive QP. (X264_AQ_*) */
        /*f_aq_strength是x264编码器中的参数之一，用于控制自适应量化模式（Adaptive Quantization Mode）中的强度设置。在AQ_ENABLED模式下，x264编码器采用自动增益控制算法，根据参考帧之间的对比度信息选择适当的强度。f_aq_strength则指定了增益控制算法中的最大增益值。该值越大，则可以应对更大的对比度变化，但也可能导致过量增益造成图像细节的损失。一般情况下，f_aq_strength的默认值为1。可以根据具体情况进行调整。*/
        float       f_aq_strength;
        /*b_mb_tree是x264编码器中的参数之一，用于控制并行B帧编码时是否使用决策树算法（Macroblock Tree）。在B帧前向预测和双向预测过程中，决策树算法可以分析参考帧的相关性，确定最优的编码方式，从而提高编码效率和图像质量。当b_mb_tree设置为1时，表示启用该算法进行B帧编码；当b_mb_tree设置为0时，则不启用该算法。启用决策树算法需要较大的计算量，可能导致编码时间的增加，但也有助于提高编码效果。一般情况下，b_mb_tree的默认值为1。*/
        int         b_mb_tree;      /* Macroblock-tree ratecontrol. */
        /*i_lookahead是x264编码器中的参数之一，用于控制编码器预测下一个编码块时使用的参考帧数。该参数的值越大，预测的精度也就越高，压缩比也会相应地提高，但编码器的延迟和实时性也将降低。通常情况下，i_lookahead参数的默认值是40，可以针对具体情况进行调整。

例如，当使用x264进行视频实时传输的时候，为了保证视频播放的实时性，可以通过降低i_lookahead参数的值来减小编码器的延迟，从而提高视频传输的实时性。但在需要更高压缩率的场景下，可以调高i_lookahead参数的值，以取得更好的压缩效果。*/
        int         i_lookahead;

        /* 2pass */
        /*在视频编码过程中，影响编码效果的因素有很多，其中参考帧的选择和排序是非常关键的一项。编码器需要根据参考帧列表来选择参考帧，以获得更好的编码效果。因此，b_stat_write参数的作用是记录每个B帧参考的P帧和I帧，建立参考帧列表以供编码器使用。

具体来说，参考帧列表可以帮助编码器进行以下操作：

1. 选择最优的参考帧：参考帧列表可以告诉编码器每个B帧应该参考哪些P帧和I帧，从而选择最优的参考帧。

2. 提高编码效率：参考帧列表可以帮助编码器快速定位参考帧，从而提高编码效率。

3. 改进视频质量：参考帧列表可以用于视频质量评估，帮助评估编码效果和改进视频质量。

总的来说，b_stat_write参数可以为后续视频分析和处理提供有用的数据，有助于优化编码器和改进视频质量。*/
        int         b_stat_write;   /* Enable stat writing in psz_stat_out */

        char        *psz_stat_out;  /* output filename (in UTF-8) of the 2pass stats file */
        int         b_stat_read;    /* Read stat from psz_stat_in and use it */
        char        *psz_stat_in;   /* input filename (in UTF-8) of the 2pass stats file */

        /* 2pass params (same as ffmpeg ones) */
        /*x264_param_t 中的 f_qcompress参数是一个浮点数，用于指定量化参数的调整方式。量化是视频编码中的一项核心操作，其主要作用是将变换系数进行量化，以降低编码数据量。f_qcompress参数主要影响量化参数的调整方式，从而影响编码质量和压缩效率。

具体来说，f_qcompress参数的作用如下：

1. 控制量化参数的调整幅度：在编码过程中，编码器需要动态调整量化参数以适应视频内容的变化。f_qcompress参数可以指定量化参数的调整幅度，从而控制编码器中量化参数的调整速度和范围。

2. 影响编码质量：f_qcompress参数的设置会直接影响编码质量，因为它控制了量化参数的调整幅度。一般而言，f_qcompress值越小，量化参数的调整幅度越小，编码质量越高，但是压缩效率会降低；反之，f_qcompress值越大，编码质量越差，但是压缩效率会提高。
3. 改变编码器的行为：f_qcompress参数可以改变编码器的行为，从而导致不同的编码效果。它可以用于调整编码器的目标输出质量和压缩效率，以满足不同的应用需求。

总的来说，f_qcompress参数是影响编码质量和压缩效率的重要参数之一，在设置时需要谨慎考虑，以达到最佳的编码效果。*/
        float       f_qcompress;    /* 0.0 => cbr, 1.0 => constant qp */
        /*x264_param_t 中的 f_qblur 参数是一个浮点数，用于指定模糊区域的模糊程度。模糊（Blur）是指将图像或视频中某个区域的像素值进行平均化或混合化，以降低图像中细节的表现，使其变得更加模糊、柔和。在视频编码中，模糊通常用于降低高运动量区域的细节，从而提高编码质量和降低数据量。f_qblur 参数用于控制编码器中何时启用模糊，并控制模糊的程度。

f_qblur 的作用如下：

1. 控制编码器中模糊的使用：f_qblur 参数可以控制编码器中何时使用模糊。一般来说，当视频中出现高运动量的区域时，启用模糊可以降低噪点、减少视频质量损失。而对于静态或低运动量区域，禁用模糊可以保持视频清晰度。

2. 控制模糊程度：f_qblur 参数可以控制模糊的程度，从而控制编码器中模糊的效果。一般而言，f_qblur值越高，模糊程度越高，编码器中大运动量区域的细节越容易降低。但是，模糊程度过高可能导致视频模糊过度，从而影响视频质量。

3. 影响编码效果：f_qblur 参数可以直接影响编码效果，因为它涉及到模糊的使用和模糊程度。合理设置 f_qblur 参数可以改善编码效果，从而达到更好的视频质量和压缩效率。

总的来说，f_qblur 参数是影响编码器中模糊使用和模糊程度的重要参数之一。在设置时需要根据具体情况综合考虑，以达到最佳的编码效果。*/
        float       f_qblur;        /* temporally blur quants */
        /*x264_param_t 中的 f_complexity_blur 参数是一个浮点数，用于指定编码器在决定是否启用模糊时考虑图像复杂度的程度。在视频编码中，复杂度是指图像中细节、纹理和颜色变化的程度。f_complexity_blur参数用于控制编码器中复杂度的使用和影响程度，以调整编码器在高复杂度图像上启用模糊的策略。

f_complexity_blur 的作用如下：

1. 控制编码器中复杂度的使用：f_complexity_blur 参数可以控制编码器在决定是否应该启用模糊时考虑复杂度的程度。在高复杂度图像中，启用模糊可以降低视频质量损失和数据量，但是其对编码器负担较大。f_complexity_blur 参数可以控制编码器对复杂度的使用，从而平衡编码质量和效率。

2. 影响编码质量：f_complexity_blur 参数直接影响编码质量，因为它控制了编码器在复杂度高的图像中启用模糊的策略。一般而言，f_complexity_blur值越高，编码器越容易启用模糊，从而降低数据量和视频质量。反之，f_complexity_blur值越低，编码器越少使用模糊，从而提高编码质量。

3. 改变编码器的行为：f_complexity_blur 参数可以改变编码器的行为，从而导致不同的编码效果。它可以用于调整编码器在高复杂度图像上的策略和性能，以满足不同的应用需求。

总的来说，f_complexity_blur 参数是影响编码器对于高复杂度图像中模糊使用和停止的重要参数之一。在设置时需要考虑到编码质量和效率之间的平衡，以达到最佳的编码效果。*/
        float       f_complexity_blur; /* temporally blur complexity */
        /*x264_param_t 中的 zones 参数是一个数组，用于指定编码器在不同的区域应该使用不同的编码参数。通过 zones 参数，可以对视频区域进行分类，然后针对不同的区域使用不同的重要性、码率、qp 值等参数来进行编码，以达到更好的视觉效果和压缩效率。

zones 参数的作用如下：

1. 分区域设置编码参数：zones 参数可以让编码器针对不同的空间区域，采用不同的编码参数进行编码。比如，在视频的动态区域中采用更高的码率和更低的 qp 值，而在视频的静态区域中采用较低的码率和较高的 qp 值，从而达到良好的视觉效果和压缩效率。

2. 提高编码效果：通过 zones 参数，编码器可以根据实际情况更加细致地调整编码参数，从而进一步提高编码效果。

3. 提高压缩效率：合理使用 zones 参数可以均衡视频码率分配，从而更好地控制视频的数据量和视频质量，提高压缩效率。

总的来说，zones 参数可以提高视频编码的灵活性和效率，是视频编码中一个非常重要的参数。在实际使用中，需要根据具体情况选择合适的编码参数来达到最佳的编码效果。*/
        x264_zone_t *zones;         /* ratecontrol overrides */
        /*x264_param_t 中的 i_zones 参数是一个整数，用于指定编码器 zones 参数数组的大小。zones 参数数组用于指定编码器在不同的区域应该使用不同的编码参数。i_zones 参数用于指定 zones 数组的大小，以便对各个区域进行更精细的控制。*/
        int         i_zones;        /* number of zone_t's */
        /*x264_param_t 中的 psz_zones 参数是一个指向字符型指针的指针，用于指定编码器 zones 参数数组中的区域划分字符串。zones 参数数组用于指定编码器在不同的区域应该使用不同的编码参数，而 psz_zones 参数则是为 zones 参数数组中的每个区域提供名称或描述信息。

psz_zones 参数的作用如下：

1. 提供区域名称或描述信息：psz_zones 参数可以为 zones 参数数组中的每个区域提供名称或描述信息。在视觉处理或后续操作中，可根据区域名称或描述信息来对每个区域进行不同的处理，以达到不同的视觉效果。

2. 分区调整编码参数：zones 参数用于指定编码器在不同的区域使用不同的编码参数，通过细分视频区域进行编码参数调整，以达到更好的视觉效果和压缩效率。而 psz_zones 参数则为每个区域提供名称或描述信息，方便后续处理。

3. 提高编码效果：使用 psz_zones 参数提供区域名称或描述信息，可以让编码器根据实际情况更加精细地调整编码参数，从而提高编码效果。

总的来说，psz_zones 参数可以为 zones 参数数组提供区域名称或描述信息，方便后续处理。在实际使用中，应根据需求设置相应的 psz_zones 参数。*/
        char        *psz_zones;     /* alternate method of specifying zones */
    } rc;

    /* Cropping Rectangle parameters: added to those implicitly defined by
       non-mod16 video resolutions. */
    /*x264_param_t 中的 crop_rect 参数是一个指向 x264_rect_t 类型的结构体指针，用于指定编码器对图像进行裁剪的区域。crop_rect 参数可以让编码器只对图像的指定部分进行编码，从而节省编码时间和编码数据量，并且可以达到更好的视觉效果。

crop_rect 参数的作用如下：

1. 缩小编码数据量：crop_rect 参数可以让编码器只对图像的指定部分进行编码，从而缩小编码数据量，降低数据传输和存储成本。

2. 提高编码质量：通过裁剪选定的区域，可以让编码器更加精细地进行编码，从而提高编码质量。

3. 适应不同的画面比例：crop_rect 参数可以根据需要对图像进行裁剪，以适应不同的画面比例。

总的来说，crop_rect 参数可以为编码器提供更加精细的编码区域选择，帮助编码器更好地适应不同的编码需求，减少编码数据量和提高编码质量。在实际使用中，需要根据具体情况设置相应的 crop_rect 参数。*/
    struct
    {
        unsigned int i_left;
        unsigned int i_top;
        unsigned int i_right;
        unsigned int i_bottom;
    } crop_rect;

    /* frame packing arrangement flag */
    /*x264_param_t 中的 i_frame_packing 参数是一个整数，用于指定帧包装格式。帧包装格式是指视频中两个或多个帧如何组合在一起形成一个完整的帧。i_frame_packing 参数可以控制编码器中使用的帧包装格式，以适应不同的应用需求。*/
    int i_frame_packing;

    /* alternative transfer SEI */
    /*x264_param_t中的i_alternative_transfer表示H.264中替代传输特征码（Alternative Transfer Characteristic Code），用于指定视频流的颜色空间和色彩和亮度范围。这个参数可以用来提高视频质量，并且可以让视频在不同设备上的显示效果更为接近。一般情况下，该参数会被设置为0，表示不使用替代传输特征码。如果需要使用，则可以设置为一个非零值，例如1或2。*/
    /*在H.264的视频编码标准中，SEI（Supplemental Enhancement Information，补充增强信息）是一种用于携带某些额外的信息的机制。i_alternative_transfer参数与SEI帧的关系在于，i_alternative_transfer指定了输出的视频流的颜色空间及色彩范围，而这些信息可以被包含在SEI帧中。

具体来说，如果i_alternative_transfer参数被设置为一个非零值，x264编码器会在输出的视频流中插入一个含有这个值的SEI帧，以便描述颜色空间和色彩范围的信息。在解码时，接收端可以从这个SEI帧中获取颜色空间和色彩范围的信息，并进行相应的处理。因此，i_alternative_transfer参数和SEI帧是相互关联的，其中i_alternative_transfer参数为SEI帧提供了必要的信息。*/
    int i_alternative_transfer;


    /* Muxing parameters */
    /*在x264_param_t结构体中，b_aud变量用于表示是否启用Access Unit Delimiter（简称AUD，访问单元分隔符）。AUD是一种用于划分视频码流中不同逻辑单元的标识符。如果设置了b_aud为1，则会在视频码流中插入AUD标识符，以便于视频解码器进行逐个访问单元的解码。如果设置为0，则不会插入AUD标识符。

在视频编码中，使用AUD有以下几个好处：

1. 每个访问单元都相对独立，可以更快地进行随机访问和编辑。

2. 可以更加准确地统计码率、帧率等信息，并分析视频质量。

3. 可以提高恢复单元错误（Error Resilience）的能力，当视频流出现错误时，解码器可以更容易的进行快速错误恢复。

需要注意的是，如果开启了AUD，会增加视频码流的大小，降低压缩效率。此外，在一些特殊情况下，如用于流媒体直播等低延迟场景下，AUD可能会影响视频的实时性。因此，在设置b_aud变量时需要根据具体需求进行折中考虑。*/
    int b_aud;                  /* generate access unit delimiters */
    /*在x264_param_t结构体中，b_repeat_headers变量用于表示是否在每个I帧之前都插入 SPS（Sequence Parameter Set）和 PPS（Picture Parameter Set），以保证每个 I 帧的解码都能正确进行，降低解码失败的风险。如果设置为1，则在每个 I 帧前都会插入 SPS 和 PPS；如果设置为0，则只在第一个 I 帧前插入 SPS 和 PPS。

在输出码流时，H.264 视频编码器通常会在第一个 I 帧前插入 SPS 和 PPS，以便于解码器进行初始化。而当解码器接收到一个新的 I 帧时，也需要重新进行初始化，以重新读取 SPS 和 PPS。如果b_repeat_headers为1，则每个 I 帧前都会再次插入 SPS 和 PPS，以确保解码器拥有最新和正确的参数设置，从而提高解码成功率和视频质量。如果设置为0，则在后续的 I 帧中不再插入 SPS 和 PPS，这可以减小编码后视频的码流大小，提高编码效率。*/
    int b_repeat_headers;       /* put SPS/PPS before each keyframe */
    /*在x264_param_t结构体中，b_annexb变量用于表示编码输出是否采用Annex B的码流格式。Annex B是H.264标准定义的一种码流格式，其中包含有Start Code前缀和NALU（Network Abstraction Layer Unit）分隔符。Start Code前缀是由三个字节的0x00和一个字节0x01组成，在NALU的前面作为分隔符使用。NALU分隔符则是指在NALU的尾部，添加了一个特定的字节序列，可用于分隔NALU。

当b_annexb设置为1时，编码器会使用Annex B的码流格式输出视频码流，包含有Start Code和NALU分隔符；如果设置为0，则表示使用裸流（Raw Stream）的格式输出视频码流，不包含Start Code和NALU分隔符。

对于Annex B的码流格式，由于Start Code和NALU分隔符的存在，可以更加容易地进行码流切割、解析和处理。目前H.264的大多数视频播放器和处理工具都支持Annex B格式的码流。因此，当需要进行视频码流的传输、封装或处理时，通常会选择Annex B格式输出*/
    int b_annexb;               /* if set, place start codes (4 bytes) before NAL units,
                                 * otherwise place size (4 bytes) before NAL units. */
    /*在x264_param_t结构体中，i_sps_id变量用于指定编码器输出的视频码流中SPS（Sequence Parameter Set）的ID值。SPS是H.264标准定义的一种视频编码参数集，用于描述编码视频序列的参数，例如帧率、分辨率、色彩空间等。SPS的具体参数值在同一个序列中的所有码流中都是一致的，因此只需要在第一个关键帧的前面插入一个SPS即可。

i_sps_id是SPS的ID值，在H.264标准中，SPS ID的取值范围为0～31。如果不指定 i_sps_id 的值，则默认使用0作为SPS的ID值。

需要注意的是，如果输出的码流中包含多个SPS，那么每个SPS的ID值都应该不同，以便于解码器可以正确地区分不同的SPS。如果使用了多个SPS，还需要在PPS（Picture Parameter Set）中指定SPS的ID值，以便于解码器根据ID值找到对应的SPS。*/
    int i_sps_id;               /* SPS and PPS id number */
    /*在x264_param_t结构体中，b_vfr_input变量用于表示是否使用可变帧率（VFR）的输入视频流。VFR是指输入视频流的帧率不固定，而是随时间变化的情况。在视频编码中，使用VFR输入可以提供更为准确的时间戳信息，更好地保留视频中的动态场景和细节，提高视频质量。

如果设置b_vfr_input为1，则表示输入视频流采用可变帧率方式；如果设置为0，则表示输入视频流采用固定帧率方式。在VFR输入模式下，编码器需要读取每一帧的显示时间戳信息，并将其传递给底层编码器。对于VFR输入，编码器通常会使用 “ffmpeg” 解析器，以便读取时间戳信息。

需要注意的是，在VFR输入模式下，编码输出的码率可能会变化，因为每一帧的展示时间是不确定的。因此，在使用VFR输入模式时，需要根据实际需要进行编码器参数的设置。同时，VFR输入模式也会增加编码的复杂度和计算开销，因此对于实时性要求比较高的场景，可能需要使用固定帧率的输入方式。*/
    int b_vfr_input;            /* VFR input.  If 1, use timebase and timestamps for ratecontrol purposes.
                                 * If 0, use fps only. */
    /*在x264_param_t结构体中，b_pulldown变量用于表示是否按照通过3：2拉夫（3:2 pulldown）技术转换后的方式进行编码输出。3:2 pulldown技术主要用于将24帧/秒（FPS）的影视片段转换为30帧/秒的美式电视信号。3:2 pulldown技术的原理是将每个电影的24帧分成6个组，前四组每组五张帧，第五组四张帧，第六组一张帧，然后对其运用某种方法，填补每秒6帧，使得电影能够以30帧/秒的速度播放。

如果设置b_pulldown为1，则表示按照3:2 pulldown技术进行编码输出；如果设置为0，则表示不使用3:2 pulldown技术。当b_pulldown被设置为1时，编码器会自动进行3:2 pulldown操作。

需要注意的是，3:2 pulldown技术只适用于将24 FPS的视频转换为30 FPS的电视信号。如果源视频的帧率不是24 FPS，则不应该使用3:2 pulldown技术。此外，由于3:2 pulldown操作会增加编码复杂度和计算开销，因此对实时性要求较高的场景可能需要禁用3:2 pulldown技术。*/
    int b_pulldown;             /* use explicity set timebase for CFR */
    /*在x264_param_t结构体中，i_fps_num变量用于指定输出视频的帧率分子值（numerator），即每秒钟的帧数。例如，如果i_fps_num设置为25，则表示输出视频的帧率为每秒25帧。i_fps_num通常是与i_fps_den共同使用，来确定视频的帧率信息。

需要注意的是，i_fps_num和i_fps_den是用于指定输出视频帧率的两个参数。i_fps_num表示帧率分子值，而i_fps_den表示帧率分母值。输出视频的实际帧率等于i_fps_num（分子值）除以i_fps_den（分母值）的结果。例如，如果i_fps_num=25，i_fps_den=1，则输出视频的帧率为每秒25帧；如果i_fps_num=30，i_fps_den=1，则输出视频的帧率为每秒30帧。

在进行视频编码时，合理的帧率设置可以帮助提高视频的质量和压缩效率。需要根据具体的应用场景来选择合适的帧率设置。通常，输出的视频帧率应该与源视频的帧率相匹配，并且应该根据目标设备和应用场景的要求进行调整。*/
    uint32_t i_fps_num;
    uint32_t i_fps_den;
    /*在x264_param_t结构体中，i_timebase_num变量用于表示时间基准分子值（numerator），即每一时间单位的长度。时间基准是指在编码时，以多少时间为单位来处理视频帧。例如，如果i_timebase_num设置为1，则表示时间基准为1秒；如果设置为1000，则表示时间基准为1毫秒。i_timebase_num通常是和i_timebase_den配合使用，用于确定时间基准的分数值。

需要注意的是，i_timebase_num和i_timebase_den用于指定时间基准分数值，通常情况下系统默认的时间基准是1秒。在使用x264进行视频编码时，需要根据具体要求和设备支持情况，对i_timebase_num和i_timebase_den进行适当的修改。一般来说，如果需要高精度的时间控制，可以将时间基准设置为较小的数值（如1毫秒），以提高编码的精度和实时性。如果输出视频的时间控制较为松散，可以适当增加时间基准的数值，以提高编码效率和稳定性。*/
    uint32_t i_timebase_num;    /* Timebase numerator */
    uint32_t i_timebase_den;    /* Timebase denominator */

    /*在x264_param_t结构体中，b_tff变量用于表示编码输出的视频流中是否采用顶场优先的（Top Field First，TFF）扫描顺序。在视频编码中，TFF扫描顺序是指视频的第一帧（即I帧）开始时，先扫描的是视频的上半部分（即顶场），然后再扫描下半部分（即底场）。

如果设置为1，则表示输出视频流采用TFF扫描序列；如果设置为0，则表示输出视频流采用底场优先的（Bottom Field First，BFF）扫描序列。

需要注意的是，视频扫描序列（或称扫描方向）是视频编码时非常重要的一个参数。对扫描序列的正确设置可以提高视频编码的效率和质量。通常情况下，视频源数据的扫描序列为TFF或BFF，需要根据具体情况将此参数设置为相应的值，以保证输出视频的质量和完整性。*/
    int b_tff;

    /* Pulldown:
     * The correct pic_struct must be passed with each input frame.
     * The input timebase should be the timebase corresponding to the output framerate. This should be constant.
     * e.g. for 3:2 pulldown timebase should be 1001/30000
     * The PTS passed with each frame must be the PTS of the frame after pulldown is applied.
     * Frame doubling and tripling require b_vfr_input set to zero (see H.264 Table D-1)
     *
     * Pulldown changes are not clearly defined in H.264. Therefore, it is the calling app's responsibility to manage this.
     */

    /*在x264_param_t结构体中，b_pic_struct变量用于表示编码输出的视频流中是否采用帧/场混合（Frame/Field Mixed，FFM）结构。在帧/场混合结构中，视频的编码帧被拆成两部分：一是完整的编码帧，二是由两个半帧合成的场。在输出视频流中，完整的编码帧与场以一定的顺序交错排列，以形成混合结构，提高视频的可压缩性和图像质量。

如果设置b_pic_struct为1，则表示编码输出的视频流采用帧/场混合结构；如果设置为0，则表示不采用帧/场混合结构。

需要注意的是，帧/场混合结构是一种比较特殊的视频结构，需要进行额外的处理和解码。如果使用帧/场混合结构，一方面能够提高视频的压缩性和图像质量，另一方面也会增加视频的解码复杂度。因此，在视频编码的时候，需要根据具体场景的要求进行选择，由于其复杂性，在一些低延迟应用场景（例如实时视频通信），可能不太适合使用帧/场混合结构编码。*/
    int b_pic_struct;

    /* Fake Interlaced.
     *
     * Used only when b_interlaced=0. Setting this flag makes it possible to flag the stream as PAFF interlaced yet
     * encode all frames progessively. It is useful for encoding 25p and 30p Blu-Ray streams.
     */
    /*好的，具体来说，在x264编码器中，b_interlaced和b_fake_interlaced是两种用于视频逐行扫描的实现方式，可以根据实际情况选择使用。下面是它们的特点和适用场景：

- b_interlaced：b_interlaced是利用B帧进行逐行扫描的编码方式，采用时序为逐行扫描（通过参数tff、bff等设置），并没有对图像进行隔行扫描处理。该方式的优点是简单、快速，适用于视频质量要求不高、并需要快速处理的场景。由于采用逐行扫描，可能会出现图像失真的情况，因此不适用于对视频质量有较高要求的场景。

- b_fake_interlaced：b_fake_interlaced也是一种逐行扫描的编码方式，它采用时序为逐行扫描，并对图像进行了一定程度的模拟，使编码后的视频能够产生类似隔行扫描的效果，并且能够减小图像失真的程度。与b_interlaced相比，b_fake_interlaced的优点是能够减小图像失真，但会增加一定的编码复杂性和时间。该方式适用于对视频质量有一定要求、并能够承受一定编码时间的场景。

综合来说，选择b_interlaced还是b_fake_interlaced，需要根据具体的应用场景和对视频质量、编码时间的要求进行综合考虑。*/
    /*在x264编码器中，b_fake_interlaced是一种逐行扫描的编码方式，与真正的隔行扫描方式（如PAFF、MBAFF）不同，它是通过利用B帧进行“假隔行扫描”实现的，可以减小图像失真，同时不需要进行后期的隔行扫描处理。

具体而言，b_fake_interlaced采用时序为逐行扫描，但并不对图像进行隔行扫描处理，而是在进行视频帧的编码时，利用B帧对图像进行一定程度的模拟，从而达到减少图像失真的效果。简单来说，就是通过模拟隔行扫描，达到优化视频质量的目的。

与b_interlaced相比，b_fake_interlaced能够减小图像失真，但会增加一定的编码复杂性和时间。但不同于其他隔行扫描编码方式，b_fake_interlaced可以通过逐行扫描实现“假隔行扫描”，从而兼顾了视频质量和编码效率的问题。

总之，x264编码器中的b_fake_interlaced是一种通过利用B帧进行“假隔行扫描”实现的逐行扫描的编码方式，能够减小图像失真，不同于其他隔行扫描方式，可以兼顾视频质量和编码效率的问题。*/
    /*假隔行扫描，实际是逐行扫描，模拟了隔行扫描的效果*/
    int b_fake_interlaced;

    /* Don't optimize header parameters based on video content, e.g. ensure that splitting an input video, compressing
     * each part, and stitching them back together will result in identical SPS/PPS. This is necessary for stitching
     * with container formats that don't allow multiple SPS/PPS. */
    /*不以视频内容来优化header，以保证能被附加(append)到分段的编码视频尾部。并保证当视频的各段采用完全相同的参数编码时，各段的header完全一致。*/
    int b_stitchable;

    /*x264中的b_opencl指的是是否启用OpenCL加速编码器流程的选项。OpenCL是一种跨平台的通用并行计算框架，可以对计算密集型任务进行加速。对于x264编码器来说，启用OpenCL可以提高编码速度和效率。如果b_opencl设置为1，则表示启用OpenCL加速，如果设置为0，则表示不启用。*/
    int b_opencl;            /* use OpenCL when available */
    /*i_opencl_device是x264中一个用于选择OpenCL设备的选项。OpenCL框架可以在计算机的多个设备上运行，如CPU、GPU、FPGA等。i_opencl_device选项允许用户选择使用哪个OpenCL设备进行编码，从而最大化性能和效率。它的值指定了OpenCL设备的编号，可以在命令行中使用"-opencl "选项设置。如果不设置i_opencl_device，则x264默认使用OpenCL中的第一个设备。*/
    int i_opencl_device;     /* specify count of GPU devices to skip, for CLI users */
    /*opencl_device_id是x264中一个用于选择OpenCL设备的选项，是i_opencl_device的替代选项。该选项提供更灵活的选项，允许用户使用指定的OpenCL设备ID进行编码，而不需要从编号列表中选择。用户可以在命令行中指定opencl_device_id的值来选择要使用的OpenCL设备ID。与i_opencl_device选项不同，opencl_device_id可以使用OpenCL设备的完整ID，包括Vender ID和Device ID等信息。这种方式更加直观和方便，对于专业用户来说可能更加适用。*/
    void *opencl_device_id;  /* pass explicit cl_device_id as void*, for API users */
    /*psz_clbin_file是x264中用于指定OpenCL二进制文件路径的选项。OpenCL编译器可以将OpenCL核心程序编译为二进制文件，这些文件可以在多个OpenCL设备之间传输，并且会在需要时动态加载到设备上执行。在x264编码器中，可以使用psz_clbin_file选项来指定预编译的OpenCL二进制文件，从而省去编译核心程序的时间和计算资源，提高编码器性能和效率。可以使用"-opencl-bin "命令行选项来指定psz_clbin_file的路径和名称。*/
    char *psz_clbin_file;    /* filename (in UTF-8) of the compiled OpenCL kernel cache file */

    /* Slicing parameters */
    /*i_slice_max_size是x264中一个用于控制编码器切片大小的选项，指定了每个切片（slice）的最大大小（以宏块数为单位）。x264编码器可以将编码视频按照一定的大小分成若干个切片，以进行并行编码和传输。增加i_slice_max_size的值可以让切片的大小变大，从而减少切片的数目，降低编码延迟和开销，提高编码效率。但是，过大的切片也可能导致视频质量下降或者传输性能降低。通常i_slice_max_size的默认值是0，表示使用x264编码器的默认切片大小。可以在命令行中使用"-slice-max-size "选项来设置i_slice_max_size的值。*/
    int i_slice_max_size;    /* Max size per slice in bytes; includes estimated NAL overhead. */
    /*i_slice_max_mbs是x264中一个用于控制编码器切片大小的选项，它指定了每个切片中宏块（MB）的最大数量。x264编码器可以将编码视频按照一定的大小分成若干个切片，以进行并行编码和传输。增加i_slice_max_mbs的值可以让切片中的宏块数量变多，从而减少切片的数目，降低编码延迟和开销，提高编码效率。通常i_slice_max_mbs的默认值是0，表示使用x264编码器的默认切片大小。可以在命令行中使用"-slice-max-mbs "选项来设置i_slice_max_mbs的值。*/
    int i_slice_max_mbs;     /* Max number of MBs per slice; overrides i_slice_count. */
    /*i_slice_max_mbs是x264中一个用于控制编码器切片大小的选项，它指定了每个切片中宏块（MB）的最小数量。*/
    int i_slice_min_mbs;     /* Min number of MBs per slice */
    /*i_slice_count是x264中一个用于控制编码器切片大小的选项，它指定了分割视频分段数量，即切片的总数。x264编码器可以将编码视频分成若干个切片来进行并行编码和传输，增加i_slice_count的值可以增加切片的数量，降低每个切片的大小，从而提高编码效率和视频质量。i_slice_count的默认值是0，如果设置为0，则x264编码器会根据i_slice_max_size和i_slice_max_mbs选项动态计算切片数量。可以在命令行中使用"-slices "选项来设置i_slice_count的值。*/
    int i_slice_count;       /* Number of slices per frame: forces rectangular slices. */
    /*i_slice_count_max是x264中一个用于控制编码器切片大小的选项，它指定了在任何时间内x264编码器允许的最大切片数量。x264编码器可以将编码视频分成若干个切片以进行并行编码和传输。增加i_slice_count_max可以增加允许的最大切片数，并且允许x264在需要时动态增加切片数，以提高编码效率和视频质量。值得注意的是，i_slice_count_max的值越大，x264编码器在进行并行编码和传输时占用的内存和带宽就越大，需要根据实际情况进行调整。i_slice_count_max的默认值是0，表示不限制切片数量。可以在命令行中使用"-slice-max-count "选项来设置i_slice_count_max的值。*/
    int i_slice_count_max;   /* Absolute cap on slices per frame; stops applying slice-max-size
                              * and slice-max-mbs if this is reached. */

    /* Optional callback for freeing this x264_param_t when it is done being used.
     * Only used when the x264_param_t sits in memory for an indefinite period of time,
     * i.e. when an x264_param_t is passed to x264_t in an x264_picture_t or in zones.
     * Not used when x264_encoder_reconfig is called directly. */
    /*param_free是x264中与编码参数相关的一个函数，用于释放x264_param_t结构体占用的内存空间。x264_param_t结构体是一个重要的结构体类型，存储了x264编码器的各种参数设置，包括视频分辨率、码率、帧率、参考帧数等。在使用x264编码器时，需要先构建一个x264_param_t结构体并设置相应的参数，然后再将其作为参数传递给x264编码器。在使用完毕后，需要调用param_free函数来释放x264_param_t结构体占用的内存空间，从而避免内存泄漏问题。*/
    /*在使用param_free函数时，需要注意以下几点：

1. 该函数只能释放由x264_param_t_alloc函数分配的内存，如果使用其他方式分配了内存，必须使用对应的释放函数进行释放。
2. 不要在x264编码器正在进行编码时调用param_free函数，否则可能会导致内存访问错误或崩溃。
3. 在调用param_free函数后，不要再次访问已释放的x264_param_t结构体，否则可能会导致不可预测的错误。
4. 当x264_param_t结构体作为输入参数传递给x264编码器函数后，不应再对该结构体进行修改，否则可能会导致编码器出现错误。

总之，在使用param_free函数时，需要遵循内存管理的基本原则，进行完整性检查和错误处理，以确保程序的正确性和稳定性。*/
    void (*param_free)( void* );

    /* Optional low-level callback for low-latency encoding.  Called for each output NAL unit
     * immediately after the NAL unit is finished encoding.  This allows the calling application
     * to begin processing video data (e.g. by sending packets over a network) before the frame
     * is done encoding.
     *
     * This callback MUST do the following in order to work correctly:
     * 1) Have available an output buffer of at least size nal->i_payload*3/2 + 5 + 64.
     * 2) Call x264_nal_encode( h, dst, nal ), where dst is the output buffer.
     * After these steps, the content of nal is valid and can be used in the same way as if
     * the NAL unit were output by x264_encoder_encode.
     *
     * This does not need to be synchronous with the encoding process: the data pointed to
     * by nal (both before and after x264_nal_encode) will remain valid until the next
     * x264_encoder_encode call.  The callback must be re-entrant.
     *
     * This callback does not work with frame-based threads; threads must be disabled
     * or sliced-threads enabled.  This callback also does not work as one would expect
     * with HRD -- since the buffering period SEI cannot be calculated until the frame
     * is finished encoding, it will not be sent via this callback.
     *
     * Note also that the NALs are not necessarily returned in order when sliced threads is
     * enabled.  Accordingly, the variable i_first_mb and i_last_mb are available in
     * x264_nal_t to help the calling application reorder the slices if necessary.
     *
     * When this callback is enabled, x264_encoder_encode does not return valid NALs;
     * the calling application is expected to acquire all output NALs through the callback.
     *
     * It is generally sensible to combine this callback with a use of slice-max-mbs or
     * slice-max-size.
     *
     * The opaque pointer is the opaque pointer from the input frame associated with this
     * NAL unit. This helps distinguish between nalu_process calls from different sources,
     * e.g. if doing multiple encodes in one process.
     */
    /*nalu_process是x264中处理NALU（Network Abstraction Layer Units）的函数，用于对编码器输入的视频原始数据流进行分析和处理。视频编码包括数据分割、压缩编码、传输等过程，其中NALU是视频编码中的一种数据格式，用于描述编码后的视频数据。nalu_process函数的作用是将NALU进行解析并在必要时进行一些特殊处理，例如填充、分割等。在对x264编码器进行二次开发时，常常需要对nalu_process函数进行二次开发，以适应特定的应用需求。*/
    /*在进行二次开发时，需要注意以下几点：

1. 熟悉NALU格式。理解NALU格式对于正确处理和使用nalu_process函数至关重要。了解NALU头、负载和起始码等各个部分的结构和意义需要有很好的掌握。

2. 确定处理的目的。在二次开发nalu_process函数之前，需要先确定希望实现的具体目的。这有助于选择正确的处理方法和相关参数，从而开始定制化的二次开发。

3. 不要轻易修改已有的nalu_process函数代码。x264的源码较为复杂，因此，大多数情况下，应该避免直接修改已有的nalu_process函数代码，防止引起其他问题。

4. 进行适用性测试。完成对nalu_process函数的二次开发后，应该对相关功能进行全面测试，确保修改后的程序的正确性和稳定性，避免程序出现未知错误。

总之，在进行nalu_process函数的二次开发时，需要充分理解NALU格式和x264编码器的工作原理，并遵循正确的开发流程和方法，在注重编码效果的同时，保证编码效率和稳定性。*/
    void (*nalu_process)( x264_t *h, x264_nal_t *nal, void *opaque );
} x264_param_t;

void x264_nal_encode( x264_t *h, uint8_t *dst, x264_nal_t *nal );

/****************************************************************************
 * H.264 level restriction information
 ****************************************************************************/

typedef struct x264_level_t
{
    /*x264_level_t中的level_idc变量是指视频的编码级别，即视频编码时所使用的压缩比例和分辨率等参数。不同的level_idc值对应不同的编码级别，例如Level 1对应176x144, 384 Kbps，Level 2对应352x288, 768 Kbps等。在x264编码器中，level_idc的值会影响到编码参数的选择，以保证编码结果符合对应的级别要求。*/
    uint8_t  level_idc;
    /*x264_level_t中的mbps变量是指每秒最大比特率（Maximum Bitrate Per Second），即视频编码时每秒钟可分配的最大码率。mbps和level_idc是一起考虑的，因为每个level_idc对应着不同的mbps值。在x264编码器中，mbps用于确定每个宏块（Macroblock）的最大比特率，以便控制编码输出的码率。如果所需的总码率超过最大比特率，编码器则会尝试缩小视频分辨率或降低帧率等方法来使所需的码率不超过mbps。这样可以保证视频编码后的文件不会超出给定的比特率限制，同时也可以保证视频质量的稳定性和流畅性。*/
    uint32_t mbps;        /* max macroblock processing rate (macroblocks/sec) */
    /*x264_level_t中的frame_size是指视频编码时所使用的帧大小，即视频编码后每一帧的大小。frame_size受到编码级别和分辨率等参数的影响。通常情况下，frame_size越大，每秒钟所能传输的数据也就越多，但同时也需要更高的带宽和存储空间。在使用x264编码器时，frame_size的设置通常是自动的，根据给定的分辨率和码率来自动调整帧的大小，以便在保证视频质量的前提下最大限度地压缩视频流，从而提高视频传输效率。*/
    uint32_t frame_size;  /* max frame size (macroblocks) */
    /*x264_level_t中的dbp（Decoding Picture Buffer）是指解码的图片缓冲参数。它的含义和CPB类似，都是为了控制视频传输参数以提高视频传输效率。

DBP通常有两个参数：

- dbp_size: 表示解码器的缓冲区大小，以帧为单位。解码器可以利用DBP中的帧缓存提高解码效率。适当加大DBP大小可以减少帧丢失和卡顿现象，但同时也会增加系统的内存消耗。

- max_dec_pic_buffering: 表示解码过程中最大的图像缓存数量。解码器根据这个参数决定缓存的帧数，以确保视频的连续性和稳定性。

DBP与CPB相比，它不仅会影响到编码端，还会影响到解码端。适当设置DBP参数可以提高视频的解码效率，从而提高视频的稳定性和流畅度。*/
    uint32_t dpb;         /* max decoded picture buffer (mbs) */
    uint32_t bitrate;     /* max bitrate (kbit/sec) */
    /*x264_level_t中的cpb（Coding Picture Buffer）是指编码的图片缓冲参数。它包括cpb_size和initial_cpb_removal_delay两个部分：

- cpb_size: 表示编码器使用的编码缓存大小，以比特为单位。cpb_size在流媒体传输中应该被限制，以确保编码器产生的视频数据流的码率不超过网络的带宽限制。cpb_size的值与mbps一起决定了视频码率（bps）。

- initial_cpb_removal_delay: 表示在编码开始之前，初始化cpb的帧计数。也就是编码过程中Initial CPD（Initial Coding Picture Delay）的值。它决定了最早哪一帧可以被引用。即在开始编码之前，应该等待多少帧才能生成指定格式的字节流。

cpb常用于H.264视频编码的控制指标，以保证视频传输中码率的稳定性和符合网络带宽的限制。编码参数的设置应该根据网络带宽和视频的内容特征等因素进行调整，以达到最佳的视频传输效果。*/
    uint32_t cpb;         /* max vbv buffer (kbit) */
    /*x264_level_t中的mv_range是指运动估计向量（Motion Vectors）的范围限制参数。在H.264视频编码中，MV向量是用来表示像素位移的一组值。运动估计问题可以表述为，对于给定的目标帧和一个参考帧，如何找到参考帧中最相似的像素块，并求出在目标帧中的位移，以便生成合适的MV向量。MV向量大小和范围的限制是用来控制码率和图像质量的重要参数。

mv_range用来限制MV向量的最大范围。实际上，MV向量的取值范围决定了编码器能够实现的最大数据压缩比例。mv_range越大，编码器就可以尝试更大的MV向量，从而获得更高的压缩比率和图像清晰度。但同时，mv_range的增加也会使编码器的计算量增大，从而影响编码速度。

在使用x264编码器时，mv_range的默认值为16，在某些场景下可以尝试修改mv_range参数的值，以便在编码过程中更好地控制图像质量和编码速度。*/
    uint16_t mv_range;    /* max vertical mv component range (pixels) */
    /*x264_level_t中的mvs_per_2mb是指每2个宏块（2MB）所允许的最大运动向量个数。在H.264视频编码中，每个宏块（Macroblock，MB）通常需要表示一个或多个运动向量，以便在预测过程中实现图像的补偿。mvs_per_2mb用于限制每2个宏块中运动向量的个数，以控制编码器产生的数据流大小。

mvs_per_2mb的默认值为9999，这意味着编码器可以生成尽可能多的运动向量，以提高编码的效率和图像的质量。在某些情况下，可以调整mvs_per_2mb参数的值，以便在编码过程中更好地平衡编码效率和图像质量。较高的mvs_per_2mb值可以提高图像的清晰度，但也会增加编码输出的数据量；较低的mvs_per_2mb值可以降低编码器的计算开销和输出的数据量，但可能会影响图像的质量。因此，在实践中需要综合考虑编码效率、图像质量和数据流大小等因素，来确定最合适的mvs_per_2mb值。*/
    uint8_t  mvs_per_2mb; /* max mvs per 2 consecutive mbs. */
    /*x264_level_t中的slice_rate是指编码器在运行时所允许的最大片段率。在视频编码过程中，slice是指视频帧的一个分块，每个slice由一组宏块组成，以便在压缩过程中实现并行编码。slice_rate用于控制编码器每秒钟所能够产生的最大Slice数量，以避免编码速度过慢或生成过大的视频文件。

slice_rate的值通常会受到编码分辨率、帧率、码率和图像质量等因素的影响。在使用x264编码器时，可以根据实际情况来调整slice_rate的值，以获得更高的编码效率和稳定性。适当增加slice_rate值可以提高编码器的速度和并发性，从而缩短编码时间并减少视频文件大小；但同时也可能会影响编码质量和稳定性，因此需要进行细致的分析和实验。*/
    uint8_t  slice_rate;  /* ?? */
    /*x264_level_t中的mincr是指在编码器和解码器之间交互时的最小关键帧间隔，以帧为单位。在视频编码中，关键帧通常会比其他帧更加复杂和耗时，但可以在解码时提供更好的清晰度和可靠性。mincr用于限制编码器生成的关键帧的最小间隔，以避免生成太多的关键帧，从而降低编码效率和视频传输效率。如果mincr值过小，可能会导致过多的关键帧，使视频大小增加和视频编码/解码效率降低。

可以根据视频场景和编码要求调整mincr的值，以达到在不影响视频质量的前提下，尽可能减小视频文件的大小和提高视频传输效率。mincr一般与视频的帧率、码率、分辨率等参数一起考虑来进行调整，以提高视频编码效率和性能。同时，mincr的设置也需要考虑适当的压缩比例及其对图像质量的影响，以实现最佳的视频编码效果和用户体验。*/
    uint8_t  mincr;       /* min compression ratio */
    /*x264_level_t中的bipred8x8是指在双向运动估计中使用8x8块的机制。在H.264视频编码中，双向运动估计通常使用两个参考帧来进行比较，以获得更高的编码效率和图像质量。bipred8x8机制则是在双向运动估计过程中，使用更小的8x8块（通常是4x4或8x4）来进行更精细的运动估计和预测，以提高视频质量和编码效率。

bipred8x8机制主要用于涉及高速运动或分层结构的视频场景，以提高图像的清晰度和细节。在使用x264编码器时，bipred8x8的默认值为1，也就是启用了8x8双向运动估计机制。可以根据视频场景和编码要求，适当调节bipred8x8参数的值，以获得最佳的视频编码效果和图像质量。*/
    uint8_t  bipred8x8;   /* limit bipred to >=8x8 */
    /*x264_level_t中的direct8x8是指使用8x8像素块预测图像的四叉树估计。在H.264视频编码中，P/B帧使用参考帧的预测来进行编码，其中以8x8像素块为基本单位进行预测。直接模式（Direct Mode）是指P/B帧的预测模式，其中以整个宏块为基本单位进行预测，以提高编码效率和图像质量，同时使用更大的像素块可以获得更准确的预测。

对于使用8x8像素块进行预测的直接模式，在复杂度方面要比以宏块为单位的直接模式高得多。因此，启用8x8直接模式需要更多的计算资源，但可以获得更好的图像质量和编码效率，这对于高质量、高复杂度的视频场景特别重要。

在x264编码器中，默认情况下会启用8x8直接模式（direct8x8=1），以实现更高的编码效率和图像质量。可以根据实际情况，调整该参数值来获得适合的编码效果和视频质量。*/
    uint8_t  direct8x8;   /* limit b_direct to >=8x8 */
    /*x264_level_t中的frame_only是指编码器是否仅编码帧（仅使用intra帧和P帧进行编码）。如果frame_only为1，则编码器将不会使用B帧进行编码，而只采用单向预测，这样可以极大地提高编码速度和降低延迟。但是缺点是在运动剧烈的视频中可能会出现画面损失，视频质量不如使用B帧编码。

frame_only的默认值为0，也就是启用所有类型的帧进行编码。可以根据视频场景和编码要求，适当调整frame_only参数的值，以获得最佳的视频编码效果和图像质量。如果对编码速度要求较高，可以考虑开启frame_only模式，否则建议保持默认设置。*/
    uint8_t  frame_only;  /* forbid interlacing */
} x264_level_t;

/* all of the levels defined in the standard, terminated by .level_idc=0 */
X264_API extern const x264_level_t x264_levels[];

/****************************************************************************
 * Basic parameter handling functions
 ****************************************************************************/

/* x264_param_default:
 *      fill x264_param_t with default values and do CPU detection */
void    x264_param_default( x264_param_t * );

/* x264_param_parse:
 *  set one parameter by name.
 *  returns 0 on success, or returns one of the following errors.
 *  note: BAD_VALUE occurs only if it can't even parse the value,
 *  numerical range is not checked until x264_encoder_open() or
 *  x264_encoder_reconfig().
 *  value=NULL means "true" for boolean options, but is a BAD_VALUE for non-booleans. */
#define X264_PARAM_BAD_NAME  (-1)
#define X264_PARAM_BAD_VALUE (-2)
int x264_param_parse( x264_param_t *, const char *name, const char *value );

/****************************************************************************
 * Advanced parameter handling functions
 ****************************************************************************/

/* These functions expose the full power of x264's preset-tune-profile system for
 * easy adjustment of large numbers of internal parameters.
 *
 * In order to replicate x264CLI's option handling, these functions MUST be called
 * in the following order:
 * 1) x264_param_default_preset
 * 2) Custom user options (via param_parse or directly assigned variables)
 * 3) x264_param_apply_fastfirstpass
 * 4) x264_param_apply_profile
 *
 * Additionally, x264CLI does not apply step 3 if the preset chosen is "placebo"
 * or --slow-firstpass is set. */

/* x264_param_default_preset:
 *      The same as x264_param_default, but also use the passed preset and tune
 *      to modify the default settings.
 *      (either can be NULL, which implies no preset or no tune, respectively)
 *
 *      Currently available presets are, ordered from fastest to slowest: */
static const char * const x264_preset_names[] = { "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo", 0 };

/*      The presets can also be indexed numerically, as in:
 *      x264_param_default_preset( &param, "3", ... )
 *      with ultrafast mapping to "0" and placebo mapping to "9".  This mapping may
 *      of course change if new presets are added in between, but will always be
 *      ordered from fastest to slowest.
 *
 *      Warning: the speed of these presets scales dramatically.  Ultrafast is a full
 *      100 times faster than placebo!
 *
 *      Currently available tunings are: */
static const char * const x264_tune_names[] = { "film", "animation", "grain", "stillimage", "psnr", "ssim", "fastdecode", "zerolatency", 0 };

/*      Multiple tunings can be used if separated by a delimiter in ",./-+",
 *      however multiple psy tunings cannot be used.
 *      film, animation, grain, stillimage, psnr, and ssim are psy tunings.
 *
 *      returns 0 on success, negative on failure (e.g. invalid preset/tune name). */
int     x264_param_default_preset( x264_param_t *, const char *preset, const char *tune );

/* x264_param_apply_fastfirstpass:
 *      If first-pass mode is set (rc.b_stat_read == 0, rc.b_stat_write == 1),
 *      modify the encoder settings to disable options generally not useful on
 *      the first pass. */
void    x264_param_apply_fastfirstpass( x264_param_t * );

/* x264_param_apply_profile:
 *      Applies the restrictions of the given profile.
 *      Currently available profiles are, from most to least restrictive: */
static const char * const x264_profile_names[] = { "baseline", "main", "high", "high10", "high422", "high444", 0 };

/*      (can be NULL, in which case the function will do nothing)
 *
 *      Does NOT guarantee that the given profile will be used: if the restrictions
 *      of "High" are applied to settings that are already Baseline-compatible, the
 *      stream will remain baseline.  In short, it does not increase settings, only
 *      decrease them.
 *
 *      returns 0 on success, negative on failure (e.g. invalid profile name). */
int     x264_param_apply_profile( x264_param_t *, const char *profile );

/****************************************************************************
 * Picture structures and functions
 ****************************************************************************/

/* x264_chroma_format:
 *      Specifies the chroma formats that x264 supports encoding. When this
 *      value is non-zero, then it represents a X264_CSP_* that is the only
 *      chroma format that x264 supports encoding. If the value is 0 then
 *      there are no restrictions. */
X264_API extern const int x264_chroma_format;

enum pic_struct_e
{
    PIC_STRUCT_AUTO              = 0, // automatically decide (default)
    PIC_STRUCT_PROGRESSIVE       = 1, // progressive frame
    // "TOP" and "BOTTOM" are not supported in x264 (PAFF only)
    PIC_STRUCT_TOP_BOTTOM        = 4, // top field followed by bottom
    PIC_STRUCT_BOTTOM_TOP        = 5, // bottom field followed by top
    PIC_STRUCT_TOP_BOTTOM_TOP    = 6, // top field, bottom field, top field repeated
    PIC_STRUCT_BOTTOM_TOP_BOTTOM = 7, // bottom field, top field, bottom field repeated
    PIC_STRUCT_DOUBLE            = 8, // double frame
    PIC_STRUCT_TRIPLE            = 9, // triple frame
};

typedef struct x264_hrd_t
{
        /*在x264_hrd_t结构体中，cpb_initial_arrival_time表示最初的码率控制缓冲区到达时间。这个时间变量记录了码率控制缓冲区的起始时刻，即开始编码时填充起始码率控制缓冲区的时间戳。可以通过这个变量来保证视频编码输出的一致性，比如在多个相同配置的编码器中进行负载均衡时，可以使用相同的cpb_initial_arrival_time，以保证输出的码率和比特率的一致性。

cpb_initial_arrival_time是一个64位无符号整数，表示从最初被测量的时间点(比如应用程序启动时)开始的参考时间。具体来说，当新的编码器实例启动时，它会计算出cpb_initial_arrival_time，然后使用它来调整其码率控制，以保证与其他编码器的多路输出一致。*/
    double cpb_initial_arrival_time;
    /*在x264_hrd_t结构体中，cpb_final_arrival_time表示最终的码率控制缓冲区到达时间。这个时间变量记录了码率控制缓冲区的最后一个填充内容的时间戳。在码率控制过程中，可以使用cpb_final_arrival_time来判断是否需要增加缓冲区的大小或者调整码率，以保证码率控制的准确性和一致性。

cpb_final_arrival_time是一个64位无符号整数，表示从最初被测量的时间点(比如应用程序启动时)开始的参考时间，与cpb_initial_arrival_time一起被用于计算码率控制缓冲区的填充时间间隔。当编码器完成编码过程并输出视频帧时，最终的cpb_final_arrival_time就会被计算出来。可以通过比较初始和最终的到达时间，来计算码率控制缓冲区的填充时长，调整码率控制以达到预期输出码率和比特率的要求。*/
    double cpb_final_arrival_time;
    /*在x264_hrd_t结构体中，cpb_removal_time表示码率控制缓冲区的删除时间。这个时间变量表示码率控制缓冲区中最旧的比特流数据的时间戳，也就是说，它表示已经被编码器删除的数据被解码器解码后的时间戳。可以使用cpb_removal_time来判断编码器删除数据的速度，调整码率控制算法，以达到预期输出码率和比特率的要求。

cpb_removal_time是一个64位无符号整数，表示从最初被测量的时间点(比如应用程序启动时)开始的参考时间。当编码器删除码率控制缓冲区中的比特流数据时，会将这些数据的时间戳与cpb_removal_time进行比较，从而计算码率控制缓冲区中删除数据的速度。通过比较删除速度和编码器的输入速度，就可以调整码率控制算法，以达到预期输出码率和比特率的要求。*/
    double cpb_removal_time;

        /*在x264_hrd_t结构体中，dpb_output_time表示一个帧从编码器的输入缓冲区到解码器的输出缓冲区中的传递时间，也称为该帧的"耗时"。dpb_output_time值的准确性对于正确的B帧预测和多个编码器之间的场景切换非常重要。可以使用dpb_output_time来计算帧之间的时间差异，从而优化视频帧的编码和解码过程。

dpb_output_time是一个32位无符号整数，表示从最初被测量的时间点(比如应用程序启动时)开始的参考时间。当编码器将一个帧从输入缓冲区传递到输出缓冲区时，会记录该帧的dpb_output_time。当解码器接收到该帧时，可以使用dpb_output_time计算该帧的传递时间，并在解码后为该帧打上时间戳。通过比较帧之间的时间戳和传递时间，可以优化视频编码和解码的速度，并确保各编解码器输出的视频流能够正确地拼接和播放。*/
    double dpb_output_time;
} x264_hrd_t;

/* Arbitrary user SEI:
 * Payload size is in bytes and the payload pointer must be valid.
 * Payload types and syntax can be found in Annex D of the H.264 Specification.
 * SEI payload alignment bits as described in Annex D must be included at the
 * end of the payload if needed.
 * The payload should not be NAL-encapsulated.
 * Payloads are written first in order of input, apart from in the case when HRD
 * is enabled where payloads are written after the Buffering Period SEI. */

typedef struct x264_sei_payload_t
{
    int payload_size;
    int payload_type;
    uint8_t *payload;
} x264_sei_payload_t;

typedef struct x264_sei_t
{
    int num_payloads;
    x264_sei_payload_t *payloads;
    /* In: optional callback to free each payload AND x264_sei_payload_t when used. */
    void (*sei_free)( void* );
} x264_sei_t;

typedef struct x264_image_t
{
        /*在x264中，x264_image_t结构体表示图像数据，其中的i_csp表示图像的色彩空间格式。i_csp是一个整数变量，具体取值如下：

- X264_CSP_I420：表示YUV 4:2:0格式，也是x264的默认色彩空间。

- X264_CSP_I422：表示YUV 4:2:2格式。

- X264_CSP_I444：表示YUV 4:4:4格式。

- X264_CSP_BGR：表示BGR格式。

- X264_CSP_RGB：表示RGB格式。

- X264_CSP_NV12：表示NV12格式。

- X264_CSP_NV16：表示NV16格式。

- X264_CSP_YUYV：表示YUYV格式。

- X264_CSP_YV12：表示YV12格式。

i_csp变量用于指定当前图像的色彩空间格式，从而确定图像数据的排列方式和解码方式。一般在编码视频时，需要将原始图像数据转换为x264支持的色彩空间格式，并且必须保证解码器支持指定的色彩空间格式，才能正确地解码和播放视频。*/
    int     i_csp;       /* Colorspace */
    /*在x264_image_t结构体中，i_plane变量表示图像数据的平面数量。对于不同的色彩空间格式，使用不同的平面存储图像数据。通常情况下，对于YUV格式来说，由于它是一种基于亮度和色差分离的颜色空间，因此需要使用多个平面来存储图像数据。

具体来说，当i_csp为X264_CSP_I420、X264_CSP_I422、X264_CSP_NV12或X264_CSP_NV16时，i_plane的取值为3，表示需要使用3个平面来存储原始图像数据。其中，第一个平面存储亮度(Y)分量，第二、三个平面存储色度(UV)分量。而当i_csp为X264_CSP_I444、X264_CSP_BGR或X264_CSP_RGB时，i_plane的取值为1，表示只需要使用一个平面存储原始图像数据。

i_plane变量的作用是根据图像的色彩空间格式确定需要使用的平面数量，从而确定图像数据的存储方式和解码方式。在使用x264进行视频编码时，需要保证图像数据存储方式和解码方式与图像的色彩空间格式相匹配，才能正确地编码和解码视频。*/
    int     i_plane;     /* Number of image planes */
        /*在x264_image_t结构体中，i_stride表示图像数据的行跨距，即每一行图像数据的存储长度。由于图像数据可能存在对齐需求，因此每一行图像数据可能并不是完整的图像宽度，而是按照特定的跨距进行存储的。

具体来说，i_stride的取值是一个整数，表示存储图像数据时每行的字节数，它通常大于等于图像的实际宽度。对于原始数据被填充到完整上限的I或P帧来说，i_stride通常等于图像宽度，即每行存储的图像数据完整，不需要跨越到下一行。而对于未被填充到完整上限的I或P帧来说，i_stride通常大于图像宽度，需要在行末补充特定数量的补偿字节。

i_stride变量的作用是确定所需的内存空间，从而确保足够的内存空间用于存储图像数据。在使用x264进行视频编码时，需要保证存储图像数据的内存空间和跨距值i_stride的设置与图像的大小相匹配，才能正确地编码和解码视频。*/
    int     i_stride[4]; /* Strides for each plane */
    /*在x264_image_t结构体中，plane[4]表示用于存储图像数据的平面缓冲区数组。对于像YUV 4:2:0格式这样的色彩空间，需要使用3个平面进行存储。而对于其他格式的图像数据，只需要使用一个平面进行存储。*/
    uint8_t *plane[4];   /* Pointers to each plane */
} x264_image_t;

typedef struct x264_image_properties_t
{
    /* All arrays of data here are ordered as follows:
     * each array contains one offset per macroblock, in raster scan order.  In interlaced
     * mode, top-field MBs and bottom-field MBs are interleaved at the row level.
     * Macroblocks are 16x16 blocks of pixels (with respect to the luma plane).  For the
     * purposes of calculating the number of macroblocks, width and height are rounded up to
     * the nearest 16.  If in interlaced mode, height is rounded up to the nearest 32 instead. */

    /* In: an array of quantizer offsets to be applied to this image during encoding.
     *     These are added on top of the decisions made by x264.
     *     Offsets can be fractional; they are added before QPs are rounded to integer.
     *     Adaptive quantization must be enabled to use this feature.  Behavior if quant
     *     offsets differ between encoding passes is undefined. */
    /*x264_image_properties_t结构体中的quant_offsets变量是一个指向int类型数组的指针，用来存储当前图像的量化矩阵的偏移量。量化矩阵是一种编码视频时使用的技术，它可以通过缩小数据的位深度来减小视频文件的体积，并提高压缩比率。quant_offsets变量记录了每个宏块的量化矩阵偏移量，以便在视频解码时能够正确还原数据。*/
    float *quant_offsets;
    /* In: optional callback to free quant_offsets when used.
     *     Useful if one wants to use a different quant_offset array for each frame. */
    void (*quant_offsets_free)( void* );

    /* In: optional array of flags for each macroblock.
     *     Allows specifying additional information for the encoder such as which macroblocks
     *     remain unchanged.  Usable flags are listed below.
     *     x264_param_t.analyse.b_mb_info must be set to use this, since x264 needs to track
     *     extra data internally to make full use of this information.
     *
     * Out: if b_mb_info_update is set, x264 will update this array as a result of encoding.
     *
     *      For "MBINFO_CONSTANT", it will remove this flag on any macroblock whose decoded
     *      pixels have changed.  This can be useful for e.g. noting which areas of the
     *      frame need to actually be blitted. Note: this intentionally ignores the effects
     *      of deblocking for the current frame, which should be fine unless one needs exact
     *      pixel-perfect accuracy.
     *
     *      Results for MBINFO_CONSTANT are currently only set for P-frames, and are not
     *      guaranteed to enumerate all blocks which haven't changed.  (There may be false
     *      negatives, but no false positives.)
     */
    /*x264_image_properties_t结构体中的mb_info变量是一个指向x264_macroblock_t类型数组的指针，用来存储当前图像的宏块信息。宏块是视频压缩和解压缩中的一种基本编码单元，每个宏块通常包含一些像素，并与其他宏块组成图像。mb_info变量记录图像中每个宏块的编码信息，包括运动估计和预测模式等，以便在视频解码时能够正确还原数据。*/
    uint8_t *mb_info;
    /* In: optional callback to free mb_info when used. */
    void (*mb_info_free)( void* );

    /* The macroblock is constant and remains unchanged from the previous frame. */
    #define X264_MBINFO_CONSTANT   (1<<0)
    /* More flags may be added in the future. */

    /* Out: SSIM of the the frame luma (if x264_param_t.b_ssim is set) */
    double f_ssim;
    /* Out: Average PSNR of the frame (if x264_param_t.b_psnr is set) */
    double f_psnr_avg;
    /* Out: PSNR of Y, U, and V (if x264_param_t.b_psnr is set) */
    double f_psnr[3];

    /* Out: Average effective CRF of the encoded frame */
    double f_crf_avg;
} x264_image_properties_t;

typedef struct x264_picture_t
{
    /* In: force picture type (if not auto)
     *     If x264 encoding parameters are violated in the forcing of picture types,
     *     x264 will correct the input picture type and log a warning.
     * Out: type of the picture encoded */
    /*x264_picture_t结构体是x264中用来存储图像信息的结构体之一。其中，i_type是一个整数值，表示当前图像的类型。x264中的图像类型主要有三种，分别是：

- I帧：Intra Frame，即关键帧，也叫做自身帧。在I帧中，图像的所有像素点都是独立编码的，不存在与其他帧的引用关系。I帧通常用于视频的起始位置，或者视频内容发生较大变化的位置。

- P帧：Predictive Frame，即预测帧。在P帧中，图像只引用之前的一帧或多帧图像，通过运动补偿和差分编码等技术来预测当前帧的像素数据，从而实现对运动变化的压缩。

- B帧：Bi-directional Prediction Frame，即双向预测帧。在B帧中，图像既引用之前的一帧也引用之后的一帧图像，它能够更准确地预测当前帧的像素数据和运动变化，因此对压缩率的提高有很大作用。

因此，x264_picture_t中的i_type变量表示当前图像的类型。它是一个整数值，其取值范围为：

- X264_TYPE_AUTO：自动选择图像类型；
- X264_TYPE_IDR：IDR图像类型，也就是关键帧；
- X264_TYPE_I：I帧；
- X264_TYPE_P：P帧；
- X264_TYPE_B：B帧；
- X264_TYPE_ANALYZE：预分析后的图像类型，主要用作内部状态标志。*/
    int     i_type;
    /* In: force quantizer for != X264_QP_AUTO */
    /*x264_picture_t结构体中的i_qpplus1变量是一个整型数值，表示当前图像的量化参数加1。量化参数（Quantization Parameter，简称QP）是影响视频编码效果的一个重要参数。在x264编码器中，QP值越小，压缩率越高，但图像质量越差；反之，则压缩率越低，图像质量越高。

i_qpplus1的作用是将QP值进行加1处理。这样做的目的是为了方便在码率控制过程中进行处理计算。在x264中，率控算法中对QP值的控制会通过算法计算出一个QP调整值，将原本值加上这个调整值就可以得到新的QP值。

因此，x264_picture_t结构体中的i_qpplus1变量表明当前图像的量化参数值为i_qpplus1-1。为了避免0值对x264的一些运算造成冲突，i_qpplus1的初值设置为1。*/
    int     i_qpplus1;
    /* In: pic_struct, for pulldown/doubling/etc...used only if b_pic_struct=1.
     *     use pic_struct_e for pic_struct inputs
     * Out: pic_struct element associated with frame */
    /*x264_picture_t结构体中的i_pic_struct变量是一个整型数值，表示当前图像的场/帧结构。在视频编码中，场/帧结构用于描述视频每一帧的采样方式和内部编码结构，它是影响视频压缩效率和视觉质量的重要因素。

i_pic_struct变量的取值范围如下：

- X264_PIC_STRUCT_FRAME（0）：帧结构，即完整的一帧图像，也称为“全帧”或“逐行扫描”模式。

- X264_PIC_STRUCT_FIELD_TOP（1）：顶场结构，表示当前图像只包含一帧的一半，也叫做上半场，只包含偶数行的像素数据。

- X264_PIC_STRUCT_FIELD_BOTTOM（2）：底场结构，表示当前图像只包含一帧的另一半，也叫做下半场，只包含奇数行的像素数据。

- X264_PIC_STRUCT_TOP_FIELD（3）：前一个图像顶场和当前图像底场合并结构。

- X264_PIC_STRUCT_BOTTOM_FIELD（4）：前一个图像底场和当前图像顶场合并结构。

- X264_PIC_STRUCT_TOP_BOTTOM（5）：前一个图像顶场和当前图像底场分别合并结构。

- X264_PIC_STRUCT_BOTTOM_TOP（6）：前一个图像底场和当前图像顶场分别合并结构。

对于非交错视频来说，i_pic_struct取值为X264_PIC_STRUCT_FRAME，表示当前图像为完整的一帧；对于交错视频来说，则会根据采样方式的不同，产生不同的场/帧结构。*/
    int     i_pic_struct;
    /* Out: whether this frame is a keyframe.  Important when using modes that result in
     * SEI recovery points being used instead of IDR frames. */
    int     b_keyframe;
    /* In: user pts, Out: pts of encoded picture (user)*/
    int64_t i_pts;
    /* Out: frame dts. When the pts of the first frame is close to zero,
     *      initial frames may have a negative dts which must be dealt with by any muxer */
    int64_t i_dts;
    /* In: custom encoding parameters to be set from this frame forwards
           (in coded order, not display order). If NULL, continue using
           parameters from the previous frame.  Some parameters, such as
           aspect ratio, can only be changed per-GOP due to the limitations
           of H.264 itself; in this case, the caller must force an IDR frame
           if it needs the changed parameter to apply immediately. */
    x264_param_t *param;
    /* In: raw image data */
    /* Out: reconstructed image data.  x264 may skip part of the reconstruction process,
            e.g. deblocking, in frames where it isn't necessary.  To force complete
            reconstruction, at a small speed cost, set b_full_recon. */
    x264_image_t img;
    /* In: optional information to modify encoder decisions for this frame
     * Out: information about the encoded frame */
    x264_image_properties_t prop;
    /* Out: HRD timing information. Output only when i_nal_hrd is set. */
    x264_hrd_t hrd_timing;
    /* In: arbitrary user SEI (e.g subtitles, AFDs) */
    x264_sei_t extra_sei;
    /* private user data. copied from input to output frames. */
    void *opaque;
} x264_picture_t;

/* x264_picture_init:
 *  initialize an x264_picture_t.  Needs to be done if the calling application
 *  allocates its own x264_picture_t as opposed to using x264_picture_alloc. */
void x264_picture_init( x264_picture_t *pic );

/* x264_picture_alloc:
 *  alloc data for a picture. You must call x264_picture_clean on it.
 *  returns 0 on success, or -1 on malloc failure or invalid colorspace. */
int x264_picture_alloc( x264_picture_t *pic, int i_csp, int i_width, int i_height );

/* x264_picture_clean:
 *  free associated resource for a x264_picture_t allocated with
 *  x264_picture_alloc ONLY */
void x264_picture_clean( x264_picture_t *pic );

/****************************************************************************
 * Encoder functions
 ****************************************************************************/

/* Force a link error in the case of linking against an incompatible API version.
 * Glue #defines exist to force correct macro expansion; the final output of the macro
 * is x264_encoder_open_##X264_BUILD (for purposes of dlopen). */
#define x264_encoder_glue1(x,y) x##y
#define x264_encoder_glue2(x,y) x264_encoder_glue1(x,y)
#define x264_encoder_open x264_encoder_glue2(x264_encoder_open_,X264_BUILD)

/* x264_encoder_open:
 *      create a new encoder handler, all parameters from x264_param_t are copied */
x264_t *x264_encoder_open( x264_param_t * );

/* x264_encoder_reconfig:
 *      various parameters from x264_param_t are copied.
 *      this takes effect immediately, on whichever frame is encoded next;
 *      due to delay, this may not be the next frame passed to encoder_encode.
 *      if the change should apply to some particular frame, use x264_picture_t->param instead.
 *      returns 0 on success, negative on parameter validation error.
 *      not all parameters can be changed; see the actual function for a detailed breakdown.
 *
 *      since not all parameters can be changed, moving from preset to preset may not always
 *      fully copy all relevant parameters, but should still work usably in practice. however,
 *      more so than for other presets, many of the speed shortcuts used in ultrafast cannot be
 *      switched out of; using reconfig to switch between ultrafast and other presets is not
 *      recommended without a more fine-grained breakdown of parameters to take this into account. */
int     x264_encoder_reconfig( x264_t *, x264_param_t * );
/* x264_encoder_parameters:
 *      copies the current internal set of parameters to the pointer provided
 *      by the caller.  useful when the calling application needs to know
 *      how x264_encoder_open has changed the parameters, or the current state
 *      of the encoder after multiple x264_encoder_reconfig calls.
 *      note that the data accessible through pointers in the returned param struct
 *      (e.g. filenames) should not be modified by the calling application. */
void    x264_encoder_parameters( x264_t *, x264_param_t * );
/* x264_encoder_headers:
 *      return the SPS and PPS that will be used for the whole stream.
 *      *pi_nal is the number of NAL units outputted in pp_nal.
 *      returns the number of bytes in the returned NALs.
 *      returns negative on error.
 *      the payloads of all output NALs are guaranteed to be sequential in memory. */
int     x264_encoder_headers( x264_t *, x264_nal_t **pp_nal, int *pi_nal );
/* x264_encoder_encode:
 *      encode one picture.
 *      *pi_nal is the number of NAL units outputted in pp_nal.
 *      returns the number of bytes in the returned NALs.
 *      returns negative on error and zero if no NAL units returned.
 *      the payloads of all output NALs are guaranteed to be sequential in memory. */
int     x264_encoder_encode( x264_t *, x264_nal_t **pp_nal, int *pi_nal, x264_picture_t *pic_in, x264_picture_t *pic_out );
/* x264_encoder_close:
 *      close an encoder handler */
void    x264_encoder_close( x264_t * );
/* x264_encoder_delayed_frames:
 *      return the number of currently delayed (buffered) frames
 *      this should be used at the end of the stream, to know when you have all the encoded frames. */
int     x264_encoder_delayed_frames( x264_t * );
/* x264_encoder_maximum_delayed_frames( x264_t * ):
 *      return the maximum number of delayed (buffered) frames that can occur with the current
 *      parameters. */
int     x264_encoder_maximum_delayed_frames( x264_t * );
/* x264_encoder_intra_refresh:
 *      If an intra refresh is not in progress, begin one with the next P-frame.
 *      If an intra refresh is in progress, begin one as soon as the current one finishes.
 *      Requires that b_intra_refresh be set.
 *
 *      Useful for interactive streaming where the client can tell the server that packet loss has
 *      occurred.  In this case, keyint can be set to an extremely high value so that intra refreshes
 *      only occur when calling x264_encoder_intra_refresh.
 *
 *      In multi-pass encoding, if x264_encoder_intra_refresh is called differently in each pass,
 *      behavior is undefined.
 *
 *      Should not be called during an x264_encoder_encode. */
void    x264_encoder_intra_refresh( x264_t * );
/* x264_encoder_invalidate_reference:
 *      An interactive error resilience tool, designed for use in a low-latency one-encoder-few-clients
 *      system.  When the client has packet loss or otherwise incorrectly decodes a frame, the encoder
 *      can be told with this command to "forget" the frame and all frames that depend on it, referencing
 *      only frames that occurred before the loss.  This will force a keyframe if no frames are left to
 *      reference after the aforementioned "forgetting".
 *
 *      It is strongly recommended to use a large i_dpb_size in this case, which allows the encoder to
 *      keep around extra, older frames to fall back on in case more recent frames are all invalidated.
 *      Unlike increasing i_frame_reference, this does not increase the number of frames used for motion
 *      estimation and thus has no speed impact.  It is also recommended to set a very large keyframe
 *      interval, so that keyframes are not used except as necessary for error recovery.
 *
 *      x264_encoder_invalidate_reference is not currently compatible with the use of B-frames or intra
 *      refresh.
 *
 *      In multi-pass encoding, if x264_encoder_invalidate_reference is called differently in each pass,
 *      behavior is undefined.
 *
 *      Should not be called during an x264_encoder_encode, but multiple calls can be made simultaneously.
 *
 *      Returns 0 on success, negative on failure. */
int x264_encoder_invalidate_reference( x264_t *, int64_t pts );

#ifdef __cplusplus
}
#endif

#endif
